src/etc/pkg/rust-logo.png binary
src/rt/msvc/* -whitespace
src/rt/valgrind/* -whitespace
+*.woff binary
.settings/
/build
i686-pc-mingw32/
-src/librustc/lib/llvmdeps.rs
+src/librustc_llvm/llvmdeps.rs
*.pot
* A new facility for enabling experimental features (feature gating) has
been added, using the crate-level `#[feature(foo)]` attribute.
* Managed boxes (@) are now behind a feature gate
- (`#[feature(managed_boxes)]`) in preperation for future removal. Use the
+ (`#[feature(managed_boxes)]`) in preparation for future removal. Use the
standard library's `Gc` or `Rc` types instead.
* `@mut` has been removed. Use `std::cell::{Cell, RefCell}` instead.
* Jumping back to the top of a loop is now done with `continue` instead of
* std: `fmt::Default` can be implemented for any type to provide default
formatting to the `format!` macro, as in `format!("{}", myfoo)`.
* std: The `rand` API continues to be tweaked.
- * std: The `rust_begin_unwind` function, useful for insterting breakpoints
+ * std: The `rust_begin_unwind` function, useful for inserting breakpoints
on failure in gdb, is now named `rust_fail`.
* std: The `each_key` and `each_value` methods on `HashMap` have been
replaced by the `keys` and `values` iterators.
extensible interfaces and is now implemented by two different crates:
libnative, for native threading and I/O; and libgreen, for green threading
and I/O. This paves the way for using the standard library in more limited
- embeded environments.
+ embedded environments.
* std: The `comm` module has been rewritten to be much faster, have a
simpler, more consistent API, and to work for both native and green
threading.
opt local-rust 0 "use an installed rustc rather than downloading a snapshot"
opt inject-std-version 1 "inject the current compiler version of libstd into programs"
opt llvm-static-stdcpp 0 "statically link to libstdc++ for LLVM"
-opt rpath 1 "build rpaths into rustc itself"
+opt rpath 0 "build rpaths into rustc itself"
opt nightly 0 "build nightly packages"
opt verify-install 1 "verify installed binaries work"
opt jemalloc 1 "build liballoc with jemalloc"
-.TH RUSTC "1" "March 2014" "rustc 0.11.0" "User Commands"
+.TH RUSTC "1" "March 2014" "rustc 0.12.0-pre" "User Commands"
.SH NAME
rustc \- The Rust compiler
.SH SYNOPSIS
.SH OPTIONS
+.TP
+\fB\-\-crate-name NAME\fR
+Specify the name of the crate being built
.TP
\fB\-\-crate-type=[bin|lib|dylib|rlib|staticlib]\fR
Configure the flavor of rust crate that is generated (default `bin`)
\fB\-\-pretty\fR [TYPE]
Pretty-print the input instead of compiling; valid types are: normal
(un-annotated source), expanded (crates expanded), typed (crates
-expanded, with type annotations), or identified (fully parenthesized,
-AST nodes and blocks with IDs)
+expanded, with type annotations), identified (fully parenthesized,
+AST nodes and blocks with IDs), or flowgraph=<nodeid> (graphviz
+formatted flowgraph for node)
.TP
\fB\-\-dep-info\fR [FILENAME]
Output dependency info to <filename> after compiling, in o format suitable
If specified, the compiler will save more files (.bc, .o, .no-opt.bc) generated
throughout compilation in the output directory.
.TP
-\fBno-rpath\fR
-If specified, then the rpath value for dynamic libraries will not be set in
+\fBrpath\fR
+If specified, then the rpath value for dynamic libraries will be set in
either dynamic library or executable outputs.
.TP
\fBno-prepopulate-passes\fR
-.TH RUSTDOC "1" "March 2014" "rustdoc 0.11.0" "User Commands"
+.TH RUSTDOC "1" "March 2014" "rustdoc 0.12.0-pre" "User Commands"
.SH NAME
rustdoc \- generate documentation from Rust source code
.SH SYNOPSIS
TARGET_CRATES := libc std green rustuv native flate arena glob term semver \
uuid serialize sync getopts collections num test time rand \
- url log regex graphviz core rlibc alloc debug rustrt
-HOST_CRATES := syntax rustc rustdoc fourcc hexfloat regex_macros fmt_macros
+ url log regex graphviz core rlibc alloc debug rustrt \
+ unicode
+HOST_CRATES := syntax rustc rustdoc fourcc hexfloat regex_macros fmt_macros \
+ rustc_llvm rustc_back
CRATES := $(TARGET_CRATES) $(HOST_CRATES)
TOOLS := compiletest rustdoc rustc
DEPS_core :=
DEPS_rlibc :=
+DEPS_unicode := core
DEPS_alloc := core libc native:jemalloc
DEPS_debug := std
DEPS_rustrt := alloc core libc collections native:rustrt_native
-DEPS_std := core libc rand alloc collections rustrt sync \
+DEPS_std := core libc rand alloc collections rustrt sync unicode \
native:rust_builtin native:backtrace
DEPS_graphviz := std
DEPS_green := std native:context_switch
DEPS_rustuv := std native:uv native:uv_support
DEPS_native := std
DEPS_syntax := std term serialize log fmt_macros debug
-DEPS_rustc := syntax native:rustllvm flate arena serialize getopts \
- time log graphviz debug
+DEPS_rustc := syntax flate arena serialize getopts \
+ time log graphviz debug rustc_llvm rustc_back
+DEPS_rustc_llvm := native:rustllvm libc std
+DEPS_rustc_back := std syntax rustc_llvm flate log libc
DEPS_rustdoc := rustc native:hoedown serialize getopts \
test time debug
DEPS_flate := std native:miniz
DEPS_uuid := std serialize
DEPS_sync := core alloc rustrt collections
DEPS_getopts := std
-DEPS_collections := core alloc
+DEPS_collections := core alloc unicode
DEPS_fourcc := rustc syntax std
DEPS_hexfloat := rustc syntax std
DEPS_num := std
ONLY_RLIB_alloc := 1
ONLY_RLIB_rand := 1
ONLY_RLIB_collections := 1
+ONLY_RLIB_unicode := 1
################################################################################
# You should not need to edit below this line
$(Q)cd tmp/distcheck && tar -xzf ../../dist/$(PKG_NAME)-$(CFG_BUILD).tar.gz
$(Q)mkdir -p tmp/distcheck/tarbininstall
$(Q)sh tmp/distcheck/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix=tmp/distcheck/tarbininstall
- $(Q)tmp/distcheck/tarbininstall/bin/rustc --version
$(Q)sh tmp/distcheck/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix=tmp/distcheck/tarbininstall --uninstall
$(Q)rm -Rf tmp/distcheck/$(PKG_NAME)-$(CFG_BUILD)
$(Q)rm -Rf tmp/distcheck/tarbininstall
MAYBE_DISABLE_VERIFY=
endif
-install: dist-install-dir-$(CFG_BUILD)-with-target-libs
- $(Q)sh tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)" "$(MAYBE_DISABLE_VERIFY)"
+install: dist-install-dir-$(CFG_BUILD)-with-target-libs | tmp/empty_dir
+ $(Q)cd tmp/empty_dir && sh ../../tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)" "$(MAYBE_DISABLE_VERIFY)"
# Remove tmp files while we can because they may have been created under sudo
$(Q)rm -R tmp/dist
-uninstall: dist-install-dir-$(CFG_BUILD)-with-target-libs
- $(Q)sh tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --uninstall --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)"
+uninstall: dist-install-dir-$(CFG_BUILD)-with-target-libs | tmp/empty_dir
+ $(Q)cd tmp/empty_dir && sh ../../tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --uninstall --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)"
# Remove tmp files while we can because they may have been created under sudo
$(Q)rm -R tmp/dist
+tmp/empty_dir:
+ mkdir -p $@
######################################################################
# Android remote installation
$(foreach host,$(CFG_HOST), \
$(eval LLVM_CONFIGS := $(LLVM_CONFIGS) $(LLVM_CONFIG_$(host))))
-$(S)src/librustc/lib/llvmdeps.rs: \
+$(S)src/librustc_llvm/llvmdeps.rs: \
$(LLVM_CONFIGS) \
$(S)src/etc/mklldeps.py \
$(MKFILE_DEPS)
######################################################################
# The version number
-CFG_RELEASE_NUM=0.11.0
-CFG_RELEASE_LABEL=
+CFG_RELEASE_NUM=0.12.0
+CFG_RELEASE_LABEL=-pre
+
+CFG_FILENAME_EXTRA=4e7c5e5c
ifndef CFG_ENABLE_NIGHTLY
# This is the normal version string
ifdef TRACE
CFG_RUSTC_FLAGS += -Z trace
endif
-ifdef CFG_DISABLE_RPATH
-CFG_RUSTC_FLAGS += -C no-rpath
+ifdef CFG_ENABLE_RPATH
+CFG_RUSTC_FLAGS += -C rpath
endif
# The executables crated during this compilation process have no need to include
-L "$$(LLVM_LIBDIR_$(2))" \
-L "$$(dir $$(LLVM_STDCPP_LOCATION_$(2)))" \
$$(RUSTFLAGS_$(4)) \
- --out-dir $$(@D) $$<
+ --out-dir $$(@D) \
+ -C extra-filename=-$$(CFG_FILENAME_EXTRA) \
+ $$<
@touch $$@
$$(call LIST_ALL_OLD_GLOB_MATCHES,\
$$(dir $$@)$$(call CFG_LIB_GLOB_$(2),$(4)))
define TARGET_HOST_RULES
-$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.rustc: $(S)src/librustc/lib/llvmdeps.rs
+$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.rustc_llvm: $(S)src/librustc_llvm/llvmdeps.rs
$$(TBIN$(1)_T_$(2)_H_$(3))/:
mkdir -p $$@
# The names of crates that must be tested
-# libcore tests are in a separate crate
+# libcore/libunicode tests are in a separate crate
DEPS_coretest :=
$(eval $(call RUST_CRATE,coretest))
-TEST_TARGET_CRATES = $(filter-out core,$(TARGET_CRATES)) coretest
+TEST_TARGET_CRATES = $(filter-out core unicode,$(TARGET_CRATES)) coretest
TEST_DOC_CRATES = $(DOC_CRATES)
TEST_HOST_CRATES = $(HOST_CRATES)
TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES)
# Main test targets
######################################################################
-check: cleantmptestlogs cleantestlibs tidy check-notidy
+check: cleantmptestlogs cleantestlibs check-notidy tidy
check-notidy: cleantmptestlogs cleantestlibs all check-stage2
$(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log
opt_str(&config.filter
.as_ref()
.map(|re| {
- re.to_str().into_string()
+ re.to_string().into_string()
}))));
logv(c, format!("runtool: {}", opt_str(&config.runtool)));
logv(c, format!("host-rustcflags: {}",
fn parse_expected(line_num: uint, line: &str, re: &Regex) -> Option<ExpectedError> {
re.captures(line).and_then(|caps| {
let adjusts = caps.name("adjusts").len();
- let kind = caps.name("kind").to_ascii().to_lower().into_str();
+ let kind = caps.name("kind").to_ascii().to_lower().into_string();
let msg = caps.name("msg").trim().to_string();
debug!("line={} kind={} msg={}", line_num, kind, msg);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::os;
use std::str;
use std::io::process::{ProcessExit, Command, Process, ProcessOutput};
use std::dynamic_lib::DynamicLibrary;
-fn target_env(lib_path: &str, aux_path: Option<&str>) -> Vec<(String, String)> {
+fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) {
// Need to be sure to put both the lib_path and the aux path in the dylib
// search path for the child.
let mut path = DynamicLibrary::search_path();
}
path.insert(0, Path::new(lib_path));
- // Remove the previous dylib search path var
- let var = DynamicLibrary::envvar();
- let mut env: Vec<(String,String)> = os::env();
- match env.iter().position(|&(ref k, _)| k.as_slice() == var) {
- Some(i) => { env.remove(i); }
- None => {}
- }
-
// Add the new dylib search path var
+ let var = DynamicLibrary::envvar();
let newpath = DynamicLibrary::create_path(path.as_slice());
let newpath = str::from_utf8(newpath.as_slice()).unwrap().to_string();
- env.push((var.to_string(), newpath));
- return env;
+ cmd.env(var.to_string(), newpath);
}
pub struct Result {pub status: ProcessExit, pub out: String, pub err: String}
env: Vec<(String, String)> ,
input: Option<String>) -> Option<Result> {
- let env = env.clone().append(target_env(lib_path, aux_path).as_slice());
- match Command::new(prog).args(args).env(env.as_slice()).spawn() {
+ let mut cmd = Command::new(prog);
+ cmd.args(args);
+ add_target_env(&mut cmd, lib_path, aux_path);
+ for (key, val) in env.move_iter() {
+ cmd.env(key, val);
+ }
+
+ match cmd.spawn() {
Ok(mut process) => {
for input in input.iter() {
process.stdin.get_mut_ref().write(input.as_bytes()).unwrap();
env: Vec<(String, String)> ,
input: Option<String>) -> Option<Process> {
- let env = env.clone().append(target_env(lib_path, aux_path).as_slice());
- match Command::new(prog).args(args).env(env.as_slice()).spawn() {
+ let mut cmd = Command::new(prog);
+ cmd.args(args);
+ add_target_env(&mut cmd, lib_path, aux_path);
+ for (key, val) in env.move_iter() {
+ cmd.env(key, val);
+ }
+
+ match cmd.spawn() {
Ok(mut process) => {
for input in input.iter() {
process.stdin.get_mut_ref().write(input.as_bytes()).unwrap();
cmd.arg("./src/etc/lldb_batchmode.py")
.arg(test_executable)
.arg(debugger_script)
- .env([("PYTHONPATH", config.lldb_python_dir.clone().unwrap().as_slice())]);
+ .env_set_all([("PYTHONPATH", config.lldb_python_dir.clone().unwrap().as_slice())]);
let (status, out, err) = match cmd.spawn() {
Ok(process) => {
Some(curr) => {
format!("{}{}{}", path, path_div(), curr)
}
- None => path.to_str()
+ None => path.to_string()
}
}
<link rel="shortcut icon" href="http://www.rust-lang.org/favicon.ico">
-<link href='http://fonts.googleapis.com/css?family=Source+Code+Pro:400'
- rel='stylesheet' type='text/css'>
let mut value: uint;
loop {
value = channel.recv();
- channel.send(value.to_str());
+ channel.send(value.to_string());
if value == 0 { break; }
}
}
(the second type parameter). The body itself simply loops, reading
from the channel and then sending its response back. The actual
response itself is simply the stringified version of the received value,
-`uint::to_str(value)`.
+`uint::to_string(value)`.
Here is the code for the parent task:
# let mut value: uint;
# loop {
# value = channel.recv();
-# channel.send(value.to_str());
+# channel.send(value.to_string());
# if value == 0u { break; }
# }
# }
You should see some output that looks something like this:
```{ignore}
-rustc 0.11.0-pre (443a1cd 2014-06-08 14:56:52 -0700)
-host: x86_64-unknown-linux-gnu
+rustc 0.12.0-pre (443a1cd 2014-06-08 14:56:52 -0700)
```
If you did, Rust has been installed successfully! Congrats!
Rust projects, and so it is assumed that Rust projects will use Cargo from the
beginning.
-Programmers love car analogies, so I've got a good one for you to think about
-the relationship between `cargo` and `rustc`: `rustc` is like a car, and
-`cargo` is like a robotic driver. You can drive your car yourself, of course,
-but isn't it just easier to let a computer drive it for you?
-
-Anyway, Cargo manages three things: building your code, downloading the
-dependencies your code needs, and building the dependencies your code needs.
-At first, your program doesn't have any dependencies, so we'll only be using
-the first part of its functionality. Eventually, we'll add more. Since we
-started off by using Cargo, it'll be easy to add later.
+Cargo manages three things: building your code, downloading the dependencies
+your code needs, and building the dependencies your code needs. At first, your
+program doesn't have any dependencies, so we'll only be using the first part of
+its functionality. Eventually, we'll add more. Since we started off by using
+Cargo, it'll be easy to add later.
Let's convert Hello World to Cargo. The first thing we need to do to begin using Cargo
is to install Cargo. To do this, we need to build it from source. There are no binaries
The compiler is telling us here that it was expecting to see the beginning of
an expression, and a `let` can only begin a statement, not an expression.
-However, re-assigning to a mutable binding is an expression:
+However, assigning to a variable binding is an expression:
```{rust}
-let mut x = 0i;
+let x;
let y = x = 5i;
```
We would get an error:
```{ignore,notrust}
-note: consider removing this semicolon:
- x + 1;
- ^
error: not all control paths return a value
fn add_one(x: int) -> int {
x + 1;
}
+
+note: consider removing this semicolon:
+ x + 1;
+ ^
```
Remember our earlier discussions about semicolons and `()`? Our function claims
There are some additional ways to define functions, but they involve features
that we haven't learned about yet, so let's just leave it at that for now.
+
## Comments
-return
+Now that we have some functions, it's a good idea to learn about comments.
+Comments are notes that you leave to other programmers to help explain things
+about your code. The compiler mostly ignores them.
+
+Rust has two kinds of comments that you should care about: **line comment**s
+and **doc comment**s.
+
+```{rust}
+// Line comments are anything after '//' and extend to the end of the line.
+
+let x = 5i; // this is also a line comment.
+
+// If you have a long explanation for something, you can put line comments next
+// to each other. Put a space between the // and your comment so that it's
+// more readable.
+```
+
+The other kind of comment is a doc comment. Doc comments use `///` instead of
+`//`, and support Markdown notation inside:
+
+```{rust}
+/// `hello` is a function that prints a greeting that is personalized based on
+/// the name given.
+///
+/// # Arguments
+///
+/// * `name` - The name of the person you'd like to greet.
+///
+/// # Example
+///
+/// ```rust
+/// let name = "Steve";
+/// hello(name); // prints "Hello, Steve!"
+/// ```
+fn hello(name: &str) {
+ println!("Hello, {}!", name);
+}
+```
-comments
+When writing doc comments, adding sections for any arguments, return values,
+and providing some examples of usage is very, very helpful.
+
+You can use the `rustdoc` tool to generate HTML documentation from these doc
+comments. We will talk more about `rustdoc` when we get to modules, as
+generally, you want to export documentation for a full module.
## Compound Data Types
-Tuples
+Rust, like many programming languages, has a number of different data types
+that are built-in. You've already done some simple work with integers and
+strings, but next, let's talk about some more complicated ways of storing data.
+
+### Tuples
+
+The first compound data type we're going to talk about are called **tuple**s.
+Tuples are an ordered list of a fixed size. Like this:
+
+```rust
+let x = (1i, "hello");
+```
+
+The parenthesis and commas form this two-length tuple. Here's the same code, but
+with the type annotated:
+
+```rust
+let x: (int, &str) = (1, "hello");
+```
+
+As you can see, the type of a tuple looks just like the tuple, but with each
+position having a type name rather than the value. Careful readers will also
+note that tuples are heterogeneous: we have an `int` and a `&str` in this tuple.
+You haven't seen `&str` as a type before, and we'll discuss the details of
+strings later. In systems programming languages, strings are a bit more complex
+than in other languages. For now, just read `&str` as "a string slice," and
+we'll learn more soon.
+
+You can access the fields in a tuple through a **destructuring let**. Here's
+an example:
+
+```rust
+let (x, y, z) = (1i, 2i, 3i);
+
+println!("x is {}", x);
+```
+
+Remember before when I said the left hand side of a `let` statement was more
+powerful than just assigning a binding? Here we are. We can put a pattern on
+the left hand side of the `let`, and if it matches up to the right hand side,
+we can assign multiple bindings at once. In this case, `let` 'destructures,'
+or 'breaks up,' the tuple, and assigns the bits to three bindings.
+
+This pattern is very powerful, and we'll see it repeated more later.
+
+The last thing to say about tuples is that they are only equivalent if
+the arity, types, and values are all identical.
+
+```rust
+let x = (1i, 2i, 3i);
+let y = (2i, 3i, 4i);
+
+if x == y {
+ println!("yes");
+} else {
+ println!("no");
+}
+```
+
+This will print `no`, as the values aren't equal.
+
+One other use of tuples is to return multiple values from a function:
+
+```rust
+fn next_two(x: int) -> (int, int) { (x + 1i, x + 2i) }
+
+fn main() {
+ let (x, y) = next_two(5i);
+ println!("x, y = {}, {}", x, y);
+}
+```
+
+Even though Rust functions can only return one value, a tuple _is_ one value,
+that happens to be made up of two. You can also see in this example how you
+can destructure a pattern returned by a function, as well.
+
+Tuples are a very simple data structure, and so are not often what you want.
+Let's move on to their bigger sibling, structs.
+
+### Structs
+
+A struct is another form of a 'record type,' just like a tuple. There's a
+difference: structs give each element that they contain a name, called a
+'field' or a 'member.' Check it out:
+
+```rust
+struct Point {
+ x: int,
+ y: int,
+}
+
+fn main() {
+ let origin = Point { x: 0i, y: 0i };
+
+ println!("The origin is at ({}, {})", origin.x, origin.y);
+}
+```
+
+There's a lot going on here, so let's break it down. We declare a struct with
+the `struct` keyword, and then with a name. By convention, structs begin with a
+capital letter and are also camel cased: `PointInSpace`, not `Point_In_Space`.
+
+We can create an instance of our struct via `let`, as usual, but we use a `key:
+value` style syntax to set each field. The order doesn't need to be the same as
+in the original declaration.
+
+Finally, because fields have names, we can access the field through dot
+notation: `origin.x`.
+
+The values in structs are immutable, like other bindings in Rust. However, you
+can use `mut` to make them mutable:
+
+```rust
+struct Point {
+ x: int,
+ y: int,
+}
+
+fn main() {
+ let mut point = Point { x: 0i, y: 0i };
+
+ point.x = 5;
+
+ println!("The point is at ({}, {})", point.x, point.y);
+}
+```
+
+This will print `The point is at (5, 0)`.
+
+### Tuple Structs and Newtypes
+
+Rust has another data type that's like a hybrid between a tuple and a struct,
+called a **tuple struct**. Tuple structs do have a name, but their fields
+don't:
+
+
+```
+struct Color(int, int, int);
+struct Point(int, int, int);
+```
+
+These two will not be equal, even if they have the same values:
+
+```{rust,ignore}
+let black = Color(0, 0, 0);
+let origin = Point(0, 0, 0);
+```
+
+It is almost always better to use a struct than a tuple struct. We would write
+`Color` and `Point` like this instead:
+
+```rust
+struct Color {
+ red: int,
+ blue: int,
+ green: int,
+}
+
+struct Point {
+ x: int,
+ y: int,
+ z: int,
+}
+```
+
+Now, we have actual names, rather than positions. Good names are important,
+and with a struct, we have actual names.
-Structs
+There _is_ one case when a tuple struct is very useful, though, and that's a
+tuple struct with only one element. We call this a 'newtype,' because it lets
+you create a new type that's a synonym for another one:
-Enums
+```
+struct Inches(int);
+struct Centimeters(int);
+
+let length = Inches(10);
+
+let Inches(integer_length) = length;
+println!("length is {} inches", integer_length);
+```
+
+As you can see here, you can extract the inner integer type through a
+destructuring `let`.
+
+### Enums
+
+Finally, Rust has a "sum type", an **enum**. Enums are an incredibly useful
+feature of Rust, and are used throughout the standard library. Enums look
+like this:
+
+```
+enum Ordering {
+ Less,
+ Equal,
+ Greater,
+}
+```
+
+This is an enum that is provided by the Rust standard library. An `Ordering`
+can only be _one_ of `Less`, `Equal`, or `Greater` at any given time. Here's
+an example:
+
+```rust
+let x = 5i;
+let y = 10i;
+
+let ordering = x.cmp(&y);
+
+if ordering == Less {
+ println!("less");
+} else if ordering == Greater {
+ println!("greater");
+} else if ordering == Equal {
+ println!("equal");
+}
+```
+
+`cmp` is a function that compares two things, and returns an `Ordering`. The
+call looks a little bit strange: rather than `cmp(x, y)`, we say `x.cmp(&y)`.
+We haven't covered methods and references yet, so it should look a little bit
+foreign. Right now, just pretend it says `cmp(x, y)`, and we'll get to those
+details soon.
+
+The `ordering` variable has the type `Ordering`, and so contains one of the
+three values. We can then do a bunch of `if`/`else` comparisons to check
+which one it is.
+
+However, repeated `if`/`else` comparisons get quite tedious. Rust has a feature
+that not only makes them nicer to read, but also makes sure that you never
+miss a case. Before we get to that, though, let's talk about another kind of
+enum: one with values.
+
+This enum has two variants, one of which has a value.:
+
+```
+enum OptionalInt {
+ Value(int),
+ Missing
+}
+
+fn main() {
+ let x = Value(5);
+ let y = Missing;
+
+ match x {
+ Value(n) => println!("x is {:d}", n),
+ Missing => println!("x is missing!"),
+ }
+
+ match y {
+ Value(n) => println!("y is {:d}", n),
+ Missing => println!("y is missing!"),
+ }
+}
+```
+
+This enum represents an `int` that we may or may not have. In the `Missing`
+case, we have no value, but in the `Value` case, we do. This enum is specific
+to `int`s, though. We can make it usable by any type, but we haven't quite
+gotten there yet!
+
+You can have any number of values in an enum:
+
+```
+enum OptionalColor {
+ Color(int, int, int),
+ Missing
+}
+```
+
+Enums with values are quite useful, but as I mentioned, they're even more
+useful when they're generic across types. But before we get to generics, let's
+talk about how to fix this big `if`/`else` statements we've been writing. We'll
+do that with `match`.
## Match
+Often, a simple `if`/`else` isn't enough, because you have more than two
+possible options. And `else` conditions can get incredibly complicated. So
+what's the solution?
+
+Rust has a keyword, `match`, that allows you to replace complicated `if`/`else`
+groupings with something more powerful. Check it out:
+
+```rust
+let x = 5i;
+
+match x {
+ 1 => println!("one"),
+ 2 => println!("two"),
+ 3 => println!("three"),
+ 4 => println!("four"),
+ 5 => println!("five"),
+ _ => println!("something else"),
+}
+```
+
+`match` takes an expression, and then branches based on its value. Each 'arm' of
+the branch is of the form `val => expression`. When the value matches, that arm's
+expression will be evaluated. It's called `match` because of the term 'pattern
+matching,' which `match` is an implementation of.
+
+So what's the big advantage here? Well, there are a few. First of all, `match`
+does 'exhaustiveness checking.' Do you see that last arm, the one with the
+underscore (`_`)? If we remove that arm, Rust will give us an error:
+
+```{ignore,notrust}
+error: non-exhaustive patterns: `_` not covered
+```
+
+In other words, Rust is trying to tell us we forgot a value. Because `x` is an
+integer, Rust knows that it can have a number of different values. For example,
+`6i`. But without the `_`, there is no arm that could match, and so Rust refuses
+to compile. `_` is sort of like a catch-all arm. If none of the other arms match,
+the arm with `_` will. And since we have this catch-all arm, we now have an arm
+for every possible value of `x`, and so our program will now compile.
+
+`match` statements also destructure enums, as well. Remember this code from the
+section on enums?
+
+```{rust}
+let x = 5i;
+let y = 10i;
+
+let ordering = x.cmp(&y);
+
+if ordering == Less {
+ println!("less");
+} else if ordering == Greater {
+ println!("greater");
+} else if ordering == Equal {
+ println!("equal");
+}
+```
+
+We can re-write this as a `match`:
+
+```{rust}
+let x = 5i;
+let y = 10i;
+
+match x.cmp(&y) {
+ Less => println!("less"),
+ Greater => println!("greater"),
+ Equal => println!("equal"),
+}
+```
+
+This version has way less noise, and it also checks exhaustively to make sure
+that we have covered all possible variants of `Ordering`. With our `if`/`else`
+version, if we had forgotten the `Greater` case, for example, our program would
+have happily compiled. If we forget in the `match`, it will not. Rust helps us
+make sure to cover all of our bases.
+
+`match` is also an expression, which means we can use it on the right hand side
+of a `let` binding. We could also implement the previous line like this:
+
+```
+let x = 5i;
+let y = 10i;
+
+let result = match x.cmp(&y) {
+ Less => "less",
+ Greater => "greater",
+ Equal => "equal",
+};
+
+println!("{}", result);
+```
+
+In this case, it doesn't make a lot of sense, as we are just making a temporary
+string where we don't need to, but sometimes, it's a nice pattern.
+
## Looping
-for
+Looping is the last basic construct that we haven't learned yet in Rust. Rust has
+two main looping constructs: `for` and `while`.
+
+### `for`
+
+The `for` loop is used to loop a particular number of times. Rust's `for` loops
+work a bit differently than in other systems languages, however. Rust's `for`
+loop doesn't look like this C `for` loop:
+
+```{ignore,c}
+for (x = 0; x < 10; x++) {
+ printf( "%d\n", x );
+}
+```
+
+It looks like this:
+
+```{rust}
+for x in range(0i, 10i) {
+ println!("{:d}", x);
+}
+```
+
+In slightly more abstract terms,
+
+```{ignore,notrust}
+for var in expression {
+ code
+}
+```
+
+The expression is an iterator, which we will discuss in more depth later in the
+guide. The iterator gives back a series of elements. Each element is one
+iteration of the loop. That value is then bound to the name `var`, which is
+valid for the loop body. Once the body is over, the next value is fetched from
+the iterator, and we loop another time. When there are no more values, the
+`for` loop is over.
+
+In our example, the `range` function is a function, provided by Rust, that
+takes a start and an end position, and gives an iterator over those values. The
+upper bound is exclusive, though, so our loop will print `0` through `9`, not
+`10`.
+
+Rust does not have the "C style" `for` loop on purpose. Manually controlling
+each element of the loop is complicated and error prone, even for experienced C
+developers. There's an old joke that goes, "There are two hard problems in
+computer science: naming things, cache invalidation, and off-by-one errors."
+The joke, of course, being that the setup says "two hard problems" but then
+lists three things. This happens quite a bit with "C style" `for` loops.
+
+We'll talk more about `for` when we cover **vector**s, later in the Guide.
+
+### `while`
+
+The other kind of looping construct in Rust is the `while` loop. It looks like
+this:
+
+```{rust}
+let mut x = 5u;
+let mut done = false;
+
+while !done {
+ x += x - 3;
+ println!("{}", x);
+ if x % 5 == 0 { done = true; }
+}
+```
+
+`while` loops are the correct choice when you're not sure how many times
+you need to loop.
+
+If you need an infinite loop, you may be tempted to write this:
+
+```{rust,ignore}
+while true {
+```
+
+Rust has a dedicated keyword, `loop`, to handle this case:
+
+```{rust,ignore}
+loop {
+```
+
+Rust's control-flow analysis treats this construct differently than a
+`while true`, since we know that it will always loop. The details of what
+that _means_ aren't super important to understand at this stage, but in
+general, the more information we can give to the compiler, the better it
+can do with safety and code generation. So you should always prefer
+`loop` when you plan to loop infinitely.
+
+### Ending iteration early
+
+Let's take a look at that `while` loop we had earlier:
+
+```{rust}
+let mut x = 5u;
+let mut done = false;
+
+while !done {
+ x += x - 3;
+ println!("{}", x);
+ if x % 5 == 0 { done = true; }
+}
+```
+
+We had to keep a dedicated `mut` boolean variable binding, `done`, to know
+when we should skip out of the loop. Rust has two keywords to help us with
+modifying iteration: `break` and `continue`.
+
+In this case, we can write the loop in a better way with `break`:
+
+```{rust}
+let mut x = 5u;
+
+loop {
+ x += x - 3;
+ println!("{}", x);
+ if x % 5 == 0 { break; }
+}
+```
+
+We now loop forever with `loop`, and use `break` to break out early.
+
+`continue` is similar, but instead of ending the loop, goes to the next
+iteration: This will only print the odd numbers:
+
+```
+for x in range(0i, 10i) {
+ if x % 2 == 0 { continue; }
+
+ println!("{:d}", x);
+}
+```
-while
+Both `continue` and `break` are valid in both kinds of loops.
+
+We have now learned all of the most basic Rust concepts. We're ready to start
+building our guessing game, but we need to know how to do one last thing first:
+get input from the keyboard. You can't have a guessing game without the ability
+to guess!
+
+## Standard Input
+
+Getting input from the keyboard is pretty easy, but uses some things
+we haven't seen before. Here's a simple program that reads some input,
+and then prints it back out:
+
+```{rust,ignore}
+fn main() {
+ println!("Type something!");
+
+ let input = std::io::stdin().read_line().ok().expect("Failed to read line");
+
+ println!("{}", input);
+}
+```
+
+Let's go over these chunks, one by one:
+
+```{rust}
+std::io::stdin();
+```
+
+This calls a function, `stdin()`, that lives inside the `std::io` module. As
+you can imagine, everything in `std` is provided by Rust, the 'standard
+library.' We'll talk more about the module system later.
+
+Since writing the fully qualified name all the time is annoying, we can use
+the `use` statement to import it in:
+
+```{rust}
+use std::io::stdin;
+
+stdin();
+```
+
+However, it's considered better practice to not import individual functions, but
+to import the module, and only use one level of qualification:
+
+```{rust}
+use std::io;
+
+io::stdin();
+```
+
+Let's update our example to use this style:
+
+```{rust,ignore}
+use std::io;
+
+fn main() {
+ println!("Type something!");
+
+ let input = io::stdin().read_line().ok().expect("Failed to read line");
+
+ println!("{}", input);
+}
+```
+
+Next up:
+
+```{rust,ignore}
+.read_line()
+```
+
+The `read_line()` method can be called on the result of `stdin()` to return
+a full line of input. Nice and easy.
+
+```{rust,ignore}
+.ok().expect("Failed to read line");
+```
+
+Here's the thing: reading a line from standard input could fail. For example,
+if this program isn't running in a terminal, but is running as part of a cron
+job, or some other context where there's no standard input. So Rust expects us
+to handle this case. Given that we plan on always running this program in a
+terminal, we use the `ok()` method to tell Rust that we're expecting everything
+to be just peachy, and the `expect()` method on that result to give an error
+message if our expectation goes wrong.
+
+We will cover the exact details of how all of this works later in the Guide.
+For now, this is all you need.
+
+With long lines like this, Rust gives you some flexibility with the whitespace.
+We _could_ write the example like this:
+
+```{rust,ignore}
+use std::io;
+
+fn main() {
+ println!("Type something!");
+
+ let input = io::stdin()
+ .read_line()
+ .ok()
+ .expect("Failed to read line");
+
+ println!("{}", input);
+}
+```
-loop
+Sometimes, this makes things more readable. Sometimes, less. Use your judgement
+here.
-break/continue
+That's all you need to get basic input from the standard input! It's not too
+complicated, but there are a number of small parts.
## Guessing Game: complete
#
msgid ""
msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
"POT-Creation-Date: 2014-02-03 08:13+0900\n"
"PO-Revision-Date: 2014-01-13 12:01+0900\n"
"Last-Translator: Automatically generated\n"
#| "[tarball]: http://static.rust-lang.org/dist/rust-nightly.tar.gz [win-exe]: "
#| "http://static.rust-lang.org/dist/rust-nightly-install.exe"
msgid ""
-"Use [`ToStr`](http://static.rust-lang.org/doc/master/std/to_str/trait.ToStr."
+"Use [`ToString`](http://static.rust-lang.org/doc/master/std/to_str/trait.ToString."
"html)."
msgstr ""
"[tarball]: http://static.rust-lang.org/dist/rust-nightly.tar.gz\n"
#, fuzzy
#| msgid ""
#| "~~~~ let x: f64 = 4.0; let y: uint = x as uint; assert!(y == 4u); ~~~~"
-msgid "~~~ let x: int = 42; let y: String = x.to_str(); ~~~"
+msgid "~~~ let x: int = 42; let y: String = x.to_string(); ~~~"
msgstr ""
"~~~~\n"
"let x: f64 = 4.0;\n"
#
msgid ""
msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
"POT-Creation-Date: 2014-02-03 08:13+0900\n"
"PO-Revision-Date: 2014-01-13 12:01+0900\n"
"Last-Translator: Automatically generated\n"
#
msgid ""
msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
"POT-Creation-Date: 2014-02-03 08:13+0900\n"
"PO-Revision-Date: 2014-01-13 12:01+0900\n"
"Last-Translator: Automatically generated\n"
#
msgid ""
msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
"POT-Creation-Date: 2014-02-03 08:13+0900\n"
"PO-Revision-Date: 2014-02-03 08:13+0900\n"
"Last-Translator: Automatically generated\n"
#
msgid ""
msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
"POT-Creation-Date: 2014-02-03 08:13+0900\n"
"PO-Revision-Date: 2014-01-13 12:01+0900\n"
"Last-Translator: Automatically generated\n"
#
msgid ""
msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
"POT-Creation-Date: 2014-02-03 08:13+0900\n"
"PO-Revision-Date: 2014-01-13 12:01+0900\n"
"Last-Translator: Automatically generated\n"
#
msgid ""
msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
"POT-Creation-Date: 2014-02-03 08:13+0900\n"
"PO-Revision-Date: 2014-01-13 12:01+0900\n"
"Last-Translator: Automatically generated\n"
#
msgid ""
msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
"POT-Creation-Date: 2014-02-03 08:13+0900\n"
"PO-Revision-Date: 2014-01-13 12:01+0900\n"
"Last-Translator: Automatically generated\n"
#
msgid ""
msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
"POT-Creation-Date: 2014-02-03 08:13+0900\n"
"PO-Revision-Date: 2014-01-13 12:01+0900\n"
"Last-Translator: Automatically generated\n"
#
msgid ""
msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
"POT-Creation-Date: 2014-02-03 08:13+0900\n"
"PO-Revision-Date: 2014-01-13 12:01+0900\n"
"Last-Translator: Automatically generated\n"
#
msgid ""
msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
"POT-Creation-Date: 2014-02-03 08:13+0900\n"
"PO-Revision-Date: 2014-02-03 08:13+0900\n"
"Last-Translator: Automatically generated\n"
#
msgid ""
msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
"POT-Creation-Date: 2014-02-03 08:13+0900\n"
"PO-Revision-Date: 2014-01-13 12:01+0900\n"
"Last-Translator: Automatically generated\n"
#
msgid ""
msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
"POT-Creation-Date: 2014-02-03 08:13+0900\n"
"PO-Revision-Date: 2014-01-13 12:01+0900\n"
"Last-Translator: Automatically generated\n"
#
msgid ""
msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
"POT-Creation-Date: 2014-02-03 08:13+0900\n"
"PO-Revision-Date: 2014-01-14 21:02+0900\n"
"Last-Translator: Automatically generated\n"
#| msgid "~~~~ {.ignore} // main.rs extern crate world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
msgid ""
"impl Printable for int {\n"
-" fn to_string(&self) -> String { self.to_str() }\n"
+" fn to_string(&self) -> String { self.to_string() }\n"
"}\n"
msgstr ""
"~~~~ {.ignore}\n"
#
msgid ""
msgstr ""
-"Project-Id-Version: Rust 0.11.0-pre\n"
+"Project-Id-Version: Rust 0.12.0-pre\n"
"POT-Creation-Date: 2014-02-03 08:13+0900\n"
"PO-Revision-Date: 2014-01-13 12:01+0900\n"
"Last-Translator: Automatically generated\n"
#. type: Plain text
#: src/doc/tutorial.md:2528
-msgid "#[deriving(Rand, ToStr)] enum ABC { A, B, C } ~~~"
+msgid "#[deriving(Rand, ToString)] enum ABC { A, B, C } ~~~"
msgstr ""
-"#[deriving(Rand, ToStr)]\n"
+"#[deriving(Rand, ToString)]\n"
"enum ABC { A, B, C }\n"
"~~~"
#| msgid ""
#| "The full list of derivable traits is `Eq`, `TotalEq`, `Ord`, `TotalOrd`, "
#| "`Encodable` `Decodable`, `Clone`, `DeepClone`, `Hash`, `Rand`, "
-#| "`Zero`, and `ToStr`."
+#| "`Zero`, and `ToString`."
msgid ""
"The full list of derivable traits is `Eq`, `TotalEq`, `Ord`, `TotalOrd`, "
"`Encodable` `Decodable`, `Clone`, `DeepClone`, `Hash`, `Rand`, "
-"`Default`, `Zero`, and `ToStr`."
+"`Default`, `Zero`, and `ToString`."
msgstr ""
"実装を自動的に導出可能なトレイトは、 `Eq`, `TotalEq`, `Ord`, `TotalOrd`, "
"`Encodable` `Decodable`, `Clone`, `DeepClone`, `Hash`, `Rand`, `Zero`, "
-"および `ToStr` です。."
+"および `ToString` です。."
#. type: Plain text
#: src/doc/tutorial.md:2534
src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff');
}
@font-face {
- font-family: 'Heuristica';
+ font-family: 'Source Serif Pro';
font-style: normal;
font-weight: 400;
- src: local('Heuristica Regular'), url("Heuristica-Regular.woff") format('woff');
+ src: local('Source Serif Pro'), url("SourceSerifPro-Regular.woff") format('woff');
}
@font-face {
- font-family: 'Heuristica';
+ font-family: 'Source Serif Pro';
font-style: italic;
font-weight: 400;
- src: local('Heuristica Italic'), url("Heuristica-Italic.woff") format('woff');
+ src: url("Heuristica-Italic.woff") format('woff');
}
@font-face {
- font-family: 'Heuristica';
+ font-family: 'Source Serif Pro';
font-style: normal;
font-weight: 700;
- src: local('Heuristica Bold'), url("Heuristica-Bold.woff") format('woff');
+ src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.woff") format('woff');
+}
+@font-face {
+ font-family: 'Source Code Pro';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Source Code Pro'), url("SourceCodePro-Regular.woff") format('woff');
}
*:not(body) {
body {
margin: 0 auto;
padding: 0 15px;
- font-family: "Heuristica", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-family: "Source Serif Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 18px;
color: #333;
line-height: 1.428571429;
~~~~
trait Printable {
- fn to_string(&self) -> String;
+ fn stringify(&self) -> String;
}
impl Printable for int {
- fn to_string(&self) -> String { self.to_str() }
+ fn stringify(&self) -> String { self.to_string() }
}
fn print(a: Box<Printable>) {
- println!("{}", a.to_string());
+ println!("{}", a.stringify());
}
fn main() {
An example of an owned box type and value:
~~~~
-
let x: Box<int> = box 10;
~~~~
-Owned box values exist in 1:1 correspondence with their heap allocation
-copying an owned box value makes a shallow copy of the pointer
+Owned box values exist in 1:1 correspondence with their heap allocation,
+copying an owned box value makes a shallow copy of the pointer.
Rust will consider a shallow copy of an owned box to move ownership of the value. After a value has been moved, the source location cannot be used unless it is reinitialized.
~~~~
b.x = 10;
~~~~
-If an object doesn't contain any non-Send types, it consists of a single
+If an object doesn't contain any non-`Send` types, it consists of a single
ownership tree and is itself given the `Send` trait which allows it to be sent
between tasks. Custom destructors can only be implemented directly on types
that are `Send`, but non-`Send` types can still *contain* types with custom
~~~{.ignore}
// `b/mod.rs`
pub mod c;
-pub fn foo() { println!("Foo!"; }
+pub fn foo() { println!("Foo!"); }
~~~
~~~{.ignore}
CFG_LIBDIR_RELATIVE=bin
fi
+if [ "$CFG_OSTYPE" = "pc-mingw32" ] || [ "$CFG_OSTYPE" = "w64-mingw32" ]
+then
+ CFG_LD_PATH_VAR=PATH
+ CFG_OLD_LD_PATH_VAR=$PATH
+elif [ "$CFG_OSTYPE" = "Darwin" ]
+then
+ CFG_LD_PATH_VAR=DYLD_LIBRARY_PATH
+ CFG_OLD_LD_PATH_VAR=$DYLD_LIBRARY_PATH
+else
+ CFG_LD_PATH_VAR=LD_LIBRARY_PATH
+ CFG_OLD_LD_PATH_VAR=$LD_LIBRARY_PATH
+fi
+
flag uninstall "only uninstall from the installation prefix"
opt verify 1 "verify that the installed binaries run correctly"
valopt prefix "/usr/local" "set installation prefix"
if [ -z "${CFG_UNINSTALL}" ]
then
msg "verifying platform can run binaries"
+ export $CFG_LD_PATH_VAR="${CFG_SRC_DIR}/lib":$CFG_OLD_LD_PATH_VAR
"${CFG_SRC_DIR}/bin/rustc" --version > /dev/null
if [ $? -ne 0 ]
then
err "can't execute rustc binary on this platform"
fi
+ export $CFG_LD_PATH_VAR=$CFG_OLD_LD_PATH_VAR
fi
fi
# The manifest lists all files to install
done < "${CFG_SRC_DIR}/${CFG_LIBDIR_RELATIVE}/rustlib/manifest.in"
+# Run ldconfig to make dynamic libraries available to the linker
+if [ "$CFG_OSTYPE" = "Linux" ]
+ then
+ ldconfig
+ if [ $? -ne 0 ]
+ then
+ warn "failed to run ldconfig."
+ warn "this may happen when not installing as root and may be fine"
+ fi
+fi
+
# Sanity check: can we run the installed binaries?
+#
+# As with the verification above, make sure the right LD_LIBRARY_PATH-equivalent
+# is in place. Try first without this variable, and if that fails try again with
+# the variable. If the second time tries, print a hopefully helpful message to
+# add something to the appropriate environment variable.
if [ -z "${CFG_DISABLE_VERIFY}" ]
then
msg "verifying installed binaries are executable"
- "${CFG_PREFIX}/bin/rustc" --version > /dev/null
+ "${CFG_PREFIX}/bin/rustc" --version 2> /dev/null 1> /dev/null
if [ $? -ne 0 ]
then
- ERR="can't execute installed rustc binary. "
- ERR="${ERR}installation may be broken. "
- ERR="${ERR}if this is expected then rerun install.sh with \`--disable-verify\` "
- ERR="${ERR}or \`make install\` with \`--disable-verify-install\`"
- err "${ERR}"
+ export $CFG_LD_PATH_VAR="${CFG_PREFIX}/lib":$CFG_OLD_LD_PATH_VAR
+ "${CFG_PREFIX}/bin/rustc" --version > /dev/null
+ if [ $? -ne 0 ]
+ then
+ ERR="can't execute installed rustc binary. "
+ ERR="${ERR}installation may be broken. "
+ ERR="${ERR}if this is expected then rerun install.sh with \`--disable-verify\` "
+ ERR="${ERR}or \`make install\` with \`--disable-verify-install\`"
+ err "${ERR}"
+ else
+ echo
+ echo " Note: please ensure '${CFG_PREFIX}/lib' is added to ${CFG_LD_PATH_VAR}"
+ fi
fi
fi
-
echo
echo " Rust is ready to roll."
echo
<!ENTITY rustIdent "[a-zA-Z_][a-zA-Z_0-9]*">
<!ENTITY rustIntSuf "([iu](8|16|32|64)?)?">
]>
-<language name="Rust" version="0.11.0" kateversion="2.4" section="Sources" extensions="*.rs" mimetype="text/x-rust" priority="15">
+<language name="Rust" version="0.12.0-pre" kateversion="2.4" section="Sources" extensions="*.rs" mimetype="text/x-rust" priority="15">
<highlighting>
<list name="fn">
<item> fn </item>
+++ /dev/null
-#!/usr/bin/env python2
-
-# Copyright 2014 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 <LICENSE-APACHE or
-# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-# option. This file may not be copied, modified, or distributed
-# except according to those terms.
-
-from __future__ import absolute_import, division, print_function
-import argparse
-from collections import defaultdict
-import csv
-import datetime
-import urllib2
-
-BASE_URL = 'http://www.unicode.org/Public/6.3.0/ucd/'
-DATA = 'UnicodeData.txt'
-SCRIPTS = 'Scripts.txt'
-
-# Mapping taken from Table 12 from:
-# http://www.unicode.org/reports/tr44/#General_Category_Values
-expanded_categories = {
- 'Lu': ['LC', 'L'], 'Ll': ['LC', 'L'], 'Lt': ['LC', 'L'],
- 'Lm': ['L'], 'Lo': ['L'],
- 'Mn': ['M'], 'Mc': ['M'], 'Me': ['M'],
- 'Nd': ['N'], 'Nl': ['N'], 'No': ['No'],
- 'Pc': ['P'], 'Pd': ['P'], 'Ps': ['P'], 'Pe': ['P'],
- 'Pi': ['P'], 'Pf': ['P'], 'Po': ['P'],
- 'Sm': ['S'], 'Sc': ['S'], 'Sk': ['S'], 'So': ['S'],
- 'Zs': ['Z'], 'Zl': ['Z'], 'Zp': ['Z'],
- 'Cc': ['C'], 'Cf': ['C'], 'Cs': ['C'], 'Co': ['C'], 'Cn': ['C'],
-}
-
-
-def as_4byte_uni(n):
- s = hex(n)[2:]
- return '\\U%s%s' % ('0' * (8 - len(s)), s)
-
-
-def expand_cat(c):
- return expanded_categories.get(c, []) + [c]
-
-
-def is_valid_unicode(n):
- return 0 <= n <= 0xD7FF or 0xE000 <= n <= 0x10FFFF
-
-
-def read_cats(f):
- assigned = defaultdict(list)
- for row in csv.reader(f, delimiter=';'):
- (hex, cats) = (int(row[0], 16), expand_cat(row[2]))
- if not is_valid_unicode(hex):
- continue
- for cat in cats:
- assigned[cat].append(hex)
- return assigned
-
-
-def read_scripts(f):
- assigned = defaultdict(list)
- for line in f:
- line = line.strip()
- if not line or line.startswith('#'):
- continue
- hexes, name = map(str.strip, line.split(';'))[:2]
- name = name[:name.index('#')].strip()
- if '..' not in hexes:
- hex = int(hexes, 16)
- if is_valid_unicode(hex):
- assigned[name].append(hex)
- else:
- hex1, hex2 = map(lambda s: int(s, 16), hexes.split('..'))
- for hex in xrange(hex1, hex2 + 1):
- if is_valid_unicode(hex):
- assigned[name].append(hex)
- return assigned
-
-
-def group(letters):
- letters = sorted(set(letters))
- grouped = []
- cur_start = letters.pop(0)
- cur_end = cur_start
- for letter in letters:
- assert letter > cur_end, \
- 'cur_end: %s, letter: %s' % (hex(cur_end), hex(letter))
-
- if letter == cur_end + 1:
- cur_end = letter
- else:
- grouped.append((cur_start, cur_end))
- cur_start, cur_end = letter, letter
- grouped.append((cur_start, cur_end))
- return grouped
-
-
-def ranges_to_rust(rs):
- rs = ("('%s', '%s')" % (as_4byte_uni(s), as_4byte_uni(e)) for s, e in rs)
- return ',\n '.join(rs)
-
-
-def groups_to_rust(groups):
- rust_groups = []
- for group_name in sorted(groups):
- rust_groups.append('("%s", &[\n %s\n ]),'
- % (group_name, ranges_to_rust(groups[group_name])))
- return '\n'.join(rust_groups)
-
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser(
- description='Generate Unicode character class tables.')
- aa = parser.add_argument
- aa('--local', action='store_true',
- help='When set, Scripts.txt and UnicodeData.txt will be read from '
- 'the CWD.')
- aa('--base-url', type=str, default=BASE_URL,
- help='The base URL to use for downloading Unicode data files.')
- args = parser.parse_args()
-
- if args.local:
- cats = read_cats(open(DATA))
- scripts = read_scripts(open(SCRIPTS))
- else:
- cats = read_cats(urllib2.urlopen(args.base_url + '/' + DATA))
- scripts = read_scripts(urllib2.urlopen(args.base_url + '/' + SCRIPTS))
-
- # Get Rust code for all Unicode general categories and scripts.
- combined = dict(cats, **scripts)
- unigroups = groups_to_rust({k: group(letters)
- for k, letters in combined.items()})
-
- # Now get Perl character classes that are Unicode friendly.
- perld = range(ord('0'), ord('9') + 1)
- dgroups = ranges_to_rust(group(perld + cats['Nd'][:]))
-
- perls = map(ord, ['\t', '\n', '\x0C', '\r', ' '])
- sgroups = ranges_to_rust(group(perls + cats['Z'][:]))
-
- low, up = (range(ord('a'), ord('z') + 1), range(ord('A'), ord('Z') + 1))
- perlw = [ord('_')] + perld + low + up
- wgroups = ranges_to_rust(group(perlw + cats['L'][:]))
-
- tpl = '''// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// DO NOT EDIT. Automatically generated by 'src/etc/regexp-unicode-tables'
-// on {date}.
-
-use parse::{{Class, NamedClasses}};
-
-pub static UNICODE_CLASSES: NamedClasses = &[
-
-{groups}
-
-];
-
-pub static PERLD: Class = &[
- {dgroups}
-];
-
-pub static PERLS: Class = &[
- {sgroups}
-];
-
-pub static PERLW: Class = &[
- {wgroups}
-];
-'''
- now = datetime.datetime.now()
- print(tpl.format(date=str(now), groups=unigroups,
- dgroups=dgroups, sgroups=sgroups, wgroups=wgroups))
# option. This file may not be copied, modified, or distributed
# except according to those terms.
-# This digests UnicodeData.txt and DerivedCoreProperties.txt and emits rust
-# code covering the core properties. Since this is a pretty rare event we
-# just store this out-of-line and check the unicode.rs file into git.
+# This script uses the following Unicode tables:
+# - DerivedCoreProperties.txt
+# - EastAsianWidth.txt
+# - PropList.txt
+# - Scripts.txt
+# - UnicodeData.txt
#
-# The emitted code is "the minimum we think is necessary for libstd", that
-# is, to support basic operations of the compiler and "most nontrivial rust
-# programs". It is not meant to be a complete implementation of unicode.
-# For that we recommend you use a proper binding to libicu.
+# Since this should not require frequent updates, we just store this
+# out-of-line and check the unicode.rs file into git.
import fileinput, re, os, sys, operator
+preamble = '''// Copyright 2012-2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly
+
+#![allow(missing_doc, non_uppercase_statics, non_snake_case_functions)]
+'''
+
+# Mapping taken from Table 12 from:
+# http://www.unicode.org/reports/tr44/#General_Category_Values
+expanded_categories = {
+ 'Lu': ['LC', 'L'], 'Ll': ['LC', 'L'], 'Lt': ['LC', 'L'],
+ 'Lm': ['L'], 'Lo': ['L'],
+ 'Mn': ['M'], 'Mc': ['M'], 'Me': ['M'],
+ 'Nd': ['N'], 'Nl': ['N'], 'No': ['No'],
+ 'Pc': ['P'], 'Pd': ['P'], 'Ps': ['P'], 'Pe': ['P'],
+ 'Pi': ['P'], 'Pf': ['P'], 'Po': ['P'],
+ 'Sm': ['S'], 'Sc': ['S'], 'Sk': ['S'], 'So': ['S'],
+ 'Zs': ['Z'], 'Zl': ['Z'], 'Zp': ['Z'],
+ 'Cc': ['C'], 'Cf': ['C'], 'Cs': ['C'], 'Co': ['C'], 'Cn': ['C'],
+}
def fetch(f):
if not os.path.exists(f):
sys.stderr.write("cannot load %s" % f)
exit(1)
+def is_valid_unicode(n):
+ return 0 <= n <= 0xD7FF or 0xE000 <= n <= 0x10FFFF
def load_unicode_data(f):
fetch(f)
gencats = {}
upperlower = {}
lowerupper = {}
- combines = []
+ combines = {}
canon_decomp = {}
compat_decomp = {}
- curr_cat = ""
- curr_combine = ""
- c_lo = 0
- c_hi = 0
- com_lo = 0
- com_hi = 0
for line in fileinput.input(f):
fields = line.split(";")
code_org = code
code = int(code, 16)
+ if not is_valid_unicode(code):
+ continue
+
# generate char to char direct common and simple conversions
# uppercase to lowercase
if gencat == "Lu" and lowcase != "" and code_org != lowcase:
if gencat == "Ll" and upcase != "" and code_org != upcase:
lowerupper[code] = int(upcase, 16)
+ # store decomposition, if given
if decomp != "":
if decomp.startswith('<'):
seq = []
seq.append(int(i, 16))
canon_decomp[code] = seq
- if curr_cat == "":
- curr_cat = gencat
- c_lo = code
- c_hi = code
+ # place letter in categories as appropriate
+ for cat in [gencat] + expanded_categories.get(gencat, []):
+ if cat not in gencats:
+ gencats[cat] = []
+ gencats[cat].append(code)
- if curr_cat == gencat:
- c_hi = code
- else:
- if curr_cat not in gencats:
- gencats[curr_cat] = []
+ # record combining class, if any
+ if combine != "0":
+ if combine not in combines:
+ combines[combine] = []
+ combines[combine].append(code)
- gencats[curr_cat].append((c_lo, c_hi))
- curr_cat = gencat
- c_lo = code
- c_hi = code
+ gencats = group_cats(gencats)
+ combines = to_combines(group_cats(combines))
- if curr_combine == "":
- curr_combine = combine
- com_lo = code
- com_hi = code
+ return (canon_decomp, compat_decomp, gencats, combines, lowerupper, upperlower)
- if curr_combine == combine:
- com_hi = code
+def group_cats(cats):
+ cats_out = {}
+ for cat in cats:
+ cats_out[cat] = group_cat(cats[cat])
+ return cats_out
+
+def group_cat(cat):
+ cat_out = []
+ letters = sorted(set(cat))
+ cur_start = letters.pop(0)
+ cur_end = cur_start
+ for letter in letters:
+ assert letter > cur_end, \
+ "cur_end: %s, letter: %s" % (hex(cur_end), hex(letter))
+ if letter == cur_end + 1:
+ cur_end = letter
else:
- if curr_combine != "0":
- combines.append((com_lo, com_hi, curr_combine))
- curr_combine = combine
- com_lo = code
- com_hi = code
+ cat_out.append((cur_start, cur_end))
+ cur_start = cur_end = letter
+ cat_out.append((cur_start, cur_end))
+ return cat_out
+
+def ungroup_cat(cat):
+ cat_out = []
+ for (lo, hi) in cat:
+ while lo <= hi:
+ cat_out.append(lo)
+ lo += 1
+ return cat_out
+
+def to_combines(combs):
+ combs_out = []
+ for comb in combs:
+ for (lo, hi) in combs[comb]:
+ combs_out.append((lo, hi, comb))
+ combs_out.sort(key=lambda comb: comb[0])
+ return combs_out
- return (canon_decomp, compat_decomp, gencats, combines, lowerupper, upperlower)
+def format_table_content(f, content, indent):
+ line = " "*indent
+ first = True
+ for chunk in content.split(","):
+ if len(line) + len(chunk) < 98:
+ if first:
+ line += chunk
+ else:
+ line += ", " + chunk
+ first = False
+ else:
+ f.write(line + ",\n")
+ line = " "*indent + chunk
+ f.write(line)
def load_properties(f, interestingprops):
fetch(f)
prop = m.group(3)
else:
continue
- if prop not in interestingprops:
+ if interestingprops and prop not in interestingprops:
continue
d_lo = int(d_lo, 16)
d_hi = int(d_hi, 16)
props[prop].append((d_lo, d_hi))
return props
+# load all widths of want_widths, except those in except_cats
+def load_east_asian_width(want_widths, except_cats):
+ f = "EastAsianWidth.txt"
+ fetch(f)
+ widths = {}
+ re1 = re.compile("^([0-9A-F]+);(\w+) +# (\w+)")
+ re2 = re.compile("^([0-9A-F]+)\.\.([0-9A-F]+);(\w+) +# (\w+)")
+
+ for line in fileinput.input(f):
+ width = None
+ d_lo = 0
+ d_hi = 0
+ cat = None
+ m = re1.match(line)
+ if m:
+ d_lo = m.group(1)
+ d_hi = m.group(1)
+ width = m.group(2)
+ cat = m.group(3)
+ else:
+ m = re2.match(line)
+ if m:
+ d_lo = m.group(1)
+ d_hi = m.group(2)
+ width = m.group(3)
+ cat = m.group(4)
+ else:
+ continue
+ if cat in except_cats or width not in want_widths:
+ continue
+ d_lo = int(d_lo, 16)
+ d_hi = int(d_hi, 16)
+ if width not in widths:
+ widths[width] = []
+ widths[width].append((d_lo, d_hi))
+ return widths
+
def escape_char(c):
if c <= 0xff:
return "'\\x%2.2x'" % c
return "'\\u%4.4x'" % c
return "'\\U%8.8x'" % c
-def ch_prefix(ix):
- if ix == 0:
- return " "
- if ix % 2 == 0:
- return ",\n "
- else:
- return ", "
-
def emit_bsearch_range_table(f):
f.write("""
fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
- use cmp::{Equal, Less, Greater};
- use slice::ImmutableVector;
- use option::None;
+ use core::cmp::{Equal, Less, Greater};
+ use core::slice::ImmutableVector;
+ use core::option::None;
r.bsearch(|&(lo,hi)| {
if lo <= c && c <= hi { Equal }
else if hi < c { Less }
else { Greater }
}) != None
}\n
-""");
+""")
+
+def emit_table(f, name, t_data, t_type = "&'static [(char, char)]", is_pub=True,
+ pfun=lambda x: "(%s,%s)" % (escape_char(x[0]), escape_char(x[1]))):
+ pub_string = ""
+ if is_pub:
+ pub_string = "pub "
+ f.write(" %sstatic %s: %s = &[\n" % (pub_string, name, t_type))
+ data = ""
+ first = True
+ for dat in t_data:
+ if not first:
+ data += ","
+ first = False
+ data += pfun(dat)
+ format_table_content(f, data, 8)
+ f.write("\n ];\n\n")
-def emit_property_module(f, mod, tbl):
+def emit_property_module(f, mod, tbl, emit_fn):
f.write("pub mod %s {\n" % mod)
keys = tbl.keys()
keys.sort()
-
for cat in keys:
- if cat not in ["Nd", "Nl", "No", "Cc",
- "XID_Start", "XID_Continue", "Alphabetic",
- "Lowercase", "Uppercase", "White_Space"]:
- continue
- f.write(" static %s_table : &'static [(char,char)] = &[\n" % cat)
- ix = 0
- for pair in tbl[cat]:
- f.write(ch_prefix(ix))
- f.write("(%s, %s)" % (escape_char(pair[0]), escape_char(pair[1])))
- ix += 1
- f.write("\n ];\n\n")
-
- f.write(" pub fn %s(c: char) -> bool {\n" % cat)
- f.write(" super::bsearch_range_table(c, %s_table)\n" % cat)
- f.write(" }\n\n")
+ emit_table(f, "%s_table" % cat, tbl[cat])
+ if cat in emit_fn:
+ f.write(" pub fn %s(c: char) -> bool {\n" % cat)
+ f.write(" super::bsearch_range_table(c, %s_table)\n" % cat)
+ f.write(" }\n\n")
f.write("}\n\n")
+def emit_regex_module(f, cats, w_data):
+ f.write("pub mod regex {\n")
+ regex_class = "&'static [(char, char)]"
+ class_table = "&'static [(&'static str, %s)]" % regex_class
+
+ emit_table(f, "UNICODE_CLASSES", cats, class_table,
+ pfun=lambda x: "(\"%s\",super::%s::%s_table)" % (x[0], x[1], x[0]))
+
+ f.write(" pub static PERLD: %s = super::general_category::Nd_table;\n\n"
+ % regex_class)
+ f.write(" pub static PERLS: %s = super::property::White_Space_table;\n\n"
+ % regex_class)
+
+ emit_table(f, "PERLW", w_data, regex_class)
+
+ f.write("}\n\n")
def emit_conversions_module(f, lowerupper, upperlower):
f.write("pub mod conversions {")
f.write("""
- use cmp::{Equal, Less, Greater};
- use slice::ImmutableVector;
- use tuple::Tuple2;
- use option::{Option, Some, None};
+ use core::cmp::{Equal, Less, Greater};
+ use core::slice::ImmutableVector;
+ use core::tuple::Tuple2;
+ use core::option::{Option, Some, None};
pub fn to_lower(c: char) -> char {
match bsearch_case_table(c, LuLl_table) {
})
}
-""");
- emit_caseconversion_table(f, "LuLl", upperlower)
- emit_caseconversion_table(f, "LlLu", lowerupper)
- f.write("}\n")
-
-def emit_caseconversion_table(f, name, table):
- f.write(" static %s_table : &'static [(char, char)] = &[\n" % name)
- sorted_table = sorted(table.iteritems(), key=operator.itemgetter(0))
- ix = 0
- for key, value in sorted_table:
- f.write(ch_prefix(ix))
- f.write("(%s, %s)" % (escape_char(key), escape_char(value)))
- ix += 1
- f.write("\n ];\n\n")
-
-def format_table_content(f, content, indent):
- line = " "*indent
- first = True
- for chunk in content.split(","):
- if len(line) + len(chunk) < 98:
- if first:
- line += chunk
- else:
- line += ", " + chunk
- first = False
- else:
- f.write(line + ",\n")
- line = " "*indent + chunk
- f.write(line)
-
-def emit_core_norm_module(f, canon, compat):
- canon_keys = canon.keys()
- canon_keys.sort()
+""")
+ emit_table(f, "LuLl_table",
+ sorted(upperlower.iteritems(), key=operator.itemgetter(0)), is_pub=False)
+ emit_table(f, "LlLu_table",
+ sorted(lowerupper.iteritems(), key=operator.itemgetter(0)), is_pub=False)
+ f.write("}\n\n")
- compat_keys = compat.keys()
- compat_keys.sort()
- f.write("pub mod normalization {\n");
- f.write(" use option::Option;\n");
- f.write(" use option::{Some, None};\n");
- f.write(" use slice::ImmutableVector;\n");
+def emit_charwidth_module(f, width_table):
+ f.write("pub mod charwidth {\n")
+ f.write(" use core::option::{Option, Some, None};\n")
+ f.write(" use core::slice::ImmutableVector;\n")
f.write("""
- fn bsearch_table(c: char, r: &'static [(char, &'static [char])]) -> Option<&'static [char]> {
- use cmp::{Equal, Less, Greater};
- match r.bsearch(|&(val, _)| {
- if c == val { Equal }
- else if val < c { Less }
+ fn bsearch_range_value_table(c: char, is_cjk: bool, r: &'static [(char, char, u8, u8)]) -> u8 {
+ use core::cmp::{Equal, Less, Greater};
+ match r.bsearch(|&(lo, hi, _, _)| {
+ if lo <= c && c <= hi { Equal }
+ else if hi < c { Less }
else { Greater }
}) {
Some(idx) => {
- let (_, result) = r[idx];
- Some(result)
+ let (_, _, r_ncjk, r_cjk) = r[idx];
+ if is_cjk { r_cjk } else { r_ncjk }
}
- None => None
+ None => 1
}
- }\n\n
+ }
""")
- f.write(" // Canonical decompositions\n")
- f.write(" static canonical_table : &'static [(char, &'static [char])] = &[\n")
- data = ""
- first = True
- for char in canon_keys:
- if not first:
- data += ","
- first = False
- data += "(%s,&[" % escape_char(char)
- first2 = True
- for d in canon[char]:
- if not first2:
- data += ","
- first2 = False
- data += escape_char(d)
- data += "])"
- format_table_content(f, data, 8)
- f.write("\n ];\n\n")
-
- f.write(" // Compatibility decompositions\n")
- f.write(" static compatibility_table : &'static [(char, &'static [char])] = &[\n")
- data = ""
- first = True
- for char in compat_keys:
- if not first:
- data += ","
- first = False
- data += "(%s,&[" % escape_char(char)
- first2 = True
- for d in compat[char]:
- if not first2:
- data += ","
- first2 = False
- data += escape_char(d)
- data += "])"
- format_table_content(f, data, 8)
- f.write("\n ];\n\n")
-
f.write("""
- pub fn decompose_canonical(c: char, i: |char|) { d(c, i, false); }
-
- pub fn decompose_compatible(c: char, i: |char|) { d(c, i, true); }
-
- fn d(c: char, i: |char|, k: bool) {
- use iter::Iterator;
-
- // 7-bit ASCII never decomposes
- if c <= '\\x7f' { i(c); return; }
-
- // Perform decomposition for Hangul
- if (c as u32) >= S_BASE && (c as u32) < (S_BASE + S_COUNT) {
- decompose_hangul(c, i);
- return;
+ pub fn width(c: char, is_cjk: bool) -> Option<uint> {
+ match c as uint {
+ _c @ 0 => Some(0), // null is zero width
+ cu if cu < 0x20 => None, // control sequences have no width
+ cu if cu < 0x7F => Some(1), // ASCII
+ cu if cu < 0xA0 => None, // more control sequences
+ _ => Some(bsearch_range_value_table(c, is_cjk, charwidth_table) as uint)
}
+ }
- // First check the canonical decompositions
- match bsearch_table(c, canonical_table) {
- Some(canon) => {
- for x in canon.iter() {
- d(*x, |b| i(b), k);
- }
- return;
- }
- None => ()
- }
+""")
- // Bottom out if we're not doing compat.
- if !k { i(c); return; }
+ f.write(" // character width table. Based on Markus Kuhn's free wcwidth() implementation,\n")
+ f.write(" // http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c\n")
+ emit_table(f, "charwidth_table", width_table, "&'static [(char, char, u8, u8)]", is_pub=False,
+ pfun=lambda x: "(%s,%s,%s,%s)" % (escape_char(x[0]), escape_char(x[1]), x[2], x[3]))
+ f.write("}\n")
- // Then check the compatibility decompositions
- match bsearch_table(c, compatibility_table) {
- Some(compat) => {
- for x in compat.iter() {
- d(*x, |b| i(b), k);
- }
- return;
- }
- None => ()
- }
+def emit_norm_module(f, canon, compat, combine):
+ canon_keys = canon.keys()
+ canon_keys.sort()
- // Finally bottom out.
- i(c);
- }
+ compat_keys = compat.keys()
+ compat_keys.sort()
- // Constants from Unicode 6.2.0 Section 3.12 Conjoining Jamo Behavior
- static S_BASE: u32 = 0xAC00;
- static L_BASE: u32 = 0x1100;
- static V_BASE: u32 = 0x1161;
- static T_BASE: u32 = 0x11A7;
- static L_COUNT: u32 = 19;
- static V_COUNT: u32 = 21;
- static T_COUNT: u32 = 28;
- static N_COUNT: u32 = (V_COUNT * T_COUNT);
- static S_COUNT: u32 = (L_COUNT * N_COUNT);
-
- // Decompose a precomposed Hangul syllable
- fn decompose_hangul(s: char, f: |char|) {
- use cast::transmute;
-
- let si = s as u32 - S_BASE;
-
- let li = si / N_COUNT;
- unsafe {
- f(transmute(L_BASE + li));
-
- let vi = (si % N_COUNT) / T_COUNT;
- f(transmute(V_BASE + vi));
-
- let ti = si % T_COUNT;
- if ti > 0 {
- f(transmute(T_BASE + ti));
- }
- }
- }
-}
+ f.write("pub mod normalization {\n")
+
+ def mkdata_fun(table):
+ def f(char):
+ data = "(%s,&[" % escape_char(char)
+ first = True
+ for d in table[char]:
+ if not first:
+ data += ","
+ first = False
+ data += escape_char(d)
+ data += "])"
+ return data
+ return f
-""")
+ f.write(" // Canonical decompositions\n")
+ emit_table(f, "canonical_table", canon_keys, "&'static [(char, &'static [char])]",
+ pfun=mkdata_fun(canon))
-def emit_std_norm_module(f, combine):
- f.write("pub mod normalization {\n");
- f.write(" use option::{Some, None};\n");
- f.write(" use slice::ImmutableVector;\n");
+ f.write(" // Compatibility decompositions\n")
+ emit_table(f, "compatibility_table", compat_keys, "&'static [(char, &'static [char])]",
+ pfun=mkdata_fun(compat))
f.write("""
fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
- use cmp::{Equal, Less, Greater};
+ use core::option::{Some, None};
+ use core::cmp::{Equal, Less, Greater};
+ use core::slice::ImmutableVector;
match r.bsearch(|&(lo, hi, _)| {
if lo <= c && c <= hi { Equal }
else if hi < c { Less }
}
None => 0
}
- }\n\n
+ }\n
""")
- f.write(" static combining_class_table : &'static [(char, char, u8)] = &[\n")
- ix = 0
- for pair in combine:
- f.write(ch_prefix(ix))
- f.write("(%s, %s, %s)" % (escape_char(pair[0]), escape_char(pair[1]), pair[2]))
- ix += 1
- f.write("\n ];\n\n")
+ emit_table(f, "combining_class_table", combine, "&'static [(char, char, u8)]", is_pub=False,
+ pfun=lambda x: "(%s,%s,%s)" % (escape_char(x[0]), escape_char(x[1]), x[2]))
f.write(" pub fn canonical_combining_class(c: char) -> u8 {\n"
+ " bsearch_range_value_table(c, combining_class_table)\n"
+ " }\n")
- f.write("}\n")
-
-
-preamble = '''// Copyright 2012-2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-// NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly
-
-#![allow(missing_doc, non_uppercase_statics)]
+ f.write("""
+}
-'''
+""")
-(canon_decomp, compat_decomp, gencats,
- combines, lowerupper, upperlower) = load_unicode_data("UnicodeData.txt")
+def remove_from_wtable(wtable, val):
+ wtable_out = []
+ while wtable:
+ if wtable[0][1] < val:
+ wtable_out.append(wtable.pop(0))
+ elif wtable[0][0] > val:
+ break
+ else:
+ (wt_lo, wt_hi, width, width_cjk) = wtable.pop(0)
+ if wt_lo == wt_hi == val:
+ continue
+ elif wt_lo == val:
+ wtable_out.append((wt_lo+1, wt_hi, width, width_cjk))
+ elif wt_hi == val:
+ wtable_out.append((wt_lo, wt_hi-1, width, width_cjk))
+ else:
+ wtable_out.append((wt_lo, val-1, width, width_cjk))
+ wtable_out.append((val+1, wt_hi, width, width_cjk))
+ if wtable:
+ wtable_out.extend(wtable)
+ return wtable_out
+
+def optimize_width_table(wtable):
+ wtable_out = []
+ w_this = wtable.pop(0)
+ while wtable:
+ if w_this[1] == wtable[0][0] - 1 and w_this[2:3] == wtable[0][2:3]:
+ w_tmp = wtable.pop(0)
+ w_this = (w_this[0], w_tmp[1], w_tmp[2], w_tmp[3])
+ else:
+ wtable_out.append(w_this)
+ w_this = wtable.pop(0)
+ wtable_out.append(w_this)
+ return wtable_out
-def gen_core_unicode():
- r = "core_unicode.rs"
+if __name__ == "__main__":
+ r = "unicode.rs"
if os.path.exists(r):
- os.remove(r);
+ os.remove(r)
with open(r, "w") as rf:
- # Preamble
+ # write the file's preamble
rf.write(preamble)
- emit_bsearch_range_table(rf);
- emit_property_module(rf, "general_category", gencats)
-
- emit_core_norm_module(rf, canon_decomp, compat_decomp)
+ # download and parse all the data
+ (canon_decomp, compat_decomp, gencats, combines,
+ lowerupper, upperlower) = load_unicode_data("UnicodeData.txt")
+ want_derived = ["XID_Start", "XID_Continue", "Alphabetic", "Lowercase", "Uppercase"]
+ other_derived = ["Default_Ignorable_Code_Point"]
+ derived = load_properties("DerivedCoreProperties.txt", want_derived + other_derived)
+ scripts = load_properties("Scripts.txt", [])
+ props = load_properties("PropList.txt",
+ ["White_Space", "Join_Control", "Noncharacter_Code_Point"])
+
+ # bsearch_range_table is used in all the property modules below
+ emit_bsearch_range_table(rf)
+
+ # all of these categories will also be available as \p{} in libregex
+ allcats = []
+ for (name, cat, pfuns) in ("general_category", gencats, ["N", "Cc"]), \
+ ("derived_property", derived, want_derived), \
+ ("script", scripts, []), \
+ ("property", props, ["White_Space"]):
+ emit_property_module(rf, name, cat, pfuns)
+ allcats.extend(map(lambda x: (x, name), cat))
+ allcats.sort(key=lambda c: c[0])
+
+ # the \w regex corresponds to Alphabetic + Mark + Decimal_Number +
+ # Connector_Punctuation + Join-Control according to UTS#18
+ # http://www.unicode.org/reports/tr18/#Compatibility_Properties
+ perl_words = []
+ for cat in derived["Alphabetic"], gencats["M"], gencats["Nd"], \
+ gencats["Pc"], props["Join_Control"]:
+ perl_words.extend(ungroup_cat(cat))
+ perl_words = group_cat(perl_words)
+
+ # emit lookup tables for \p{}, along with \d, \w, and \s for libregex
+ emit_regex_module(rf, allcats, perl_words)
+
+ # normalizations and conversions module
+ emit_norm_module(rf, canon_decomp, compat_decomp, combines)
+ emit_conversions_module(rf, lowerupper, upperlower)
- derived = load_properties("DerivedCoreProperties.txt",
- ["XID_Start", "XID_Continue", "Alphabetic", "Lowercase", "Uppercase"])
+ # character width module
+ width_table = []
+ for zwcat in ["Me", "Mn", "Cf"]:
+ width_table.extend(map(lambda (lo, hi): (lo, hi, 0, 0), gencats[zwcat]))
+ width_table.append((4448, 4607, 0, 0))
- emit_property_module(rf, "derived_property", derived)
+ # get widths, except those that are explicitly marked zero-width above
+ ea_widths = load_east_asian_width(["W", "F", "A"], ["Me", "Mn", "Cf"])
+ # these are doublewidth
+ for dwcat in ["W", "F"]:
+ width_table.extend(map(lambda (lo, hi): (lo, hi, 2, 2), ea_widths[dwcat]))
+ width_table.extend(map(lambda (lo, hi): (lo, hi, 1, 2), ea_widths["A"]))
- props = load_properties("PropList.txt", ["White_Space"])
- emit_property_module(rf, "property", props)
- emit_conversions_module(rf, lowerupper, upperlower)
+ width_table.sort(key=lambda w: w[0])
-def gen_std_unicode():
- r = "std_unicode.rs"
- if os.path.exists(r):
- os.remove(r);
- with open(r, "w") as rf:
- # Preamble
- rf.write(preamble)
- emit_std_norm_module(rf, combines)
+ # soft hyphen is not zero width in preformatted text; it's used to indicate
+ # a hyphen inserted to facilitate a linebreak.
+ width_table = remove_from_wtable(width_table, 173)
-gen_core_unicode()
-gen_std_unicode()
+ # optimize the width table by collapsing adjacent entities when possible
+ width_table = optimize_width_table(width_table)
+ emit_charwidth_module(rf, width_table)
" j was only added in 7.3.541, so stop complaints about its nonexistence
silent! setlocal formatoptions+=j
+" smartindent will be overridden by indentexpr if filetype indent is on, but
+" otherwise it's better than nothing.
+setlocal smartindent nocindent
+
+setlocal tabstop=4 shiftwidth=4 expandtab
+
" This includeexpr isn't perfect, but it's a good start
setlocal includeexpr=substitute(v:fname,'::','/','g')
syn keyword rustTrait Add Sub Mul Div Rem Neg Not
syn keyword rustTrait BitAnd BitOr BitXor
syn keyword rustTrait Drop Deref DerefMut
-syn keyword rustTrait Shl Shr Index
+syn keyword rustTrait Shl Shr Index IndexMut
syn keyword rustEnum Option
syn keyword rustEnumVariant Some None
syn keyword rustEnum Result
syn keyword rustTrait Buffer Writer Reader Seek
syn keyword rustTrait Str StrVector StrSlice OwnedStr
syn keyword rustTrait IntoMaybeOwned StrAllocating
-syn keyword rustTrait ToStr IntoStr
+syn keyword rustTrait ToString IntoStr
syn keyword rustTrait Tuple1 Tuple2 Tuple3 Tuple4
syn keyword rustTrait Tuple5 Tuple6 Tuple7 Tuple8
syn keyword rustTrait Tuple9 Tuple10 Tuple11 Tuple12
-c'[Compile and assemble, but do not link]'
--cfg'[Configure the compilation environment]'
--crate-id'[Output the crate id and exit]'
- --crate-file-name'[Output the file(s) that would be written if compilation continued and exit]'
- --crate-name'[Output the crate name and exit]'
- --dep-info'[Output dependency info to <filename> after compiling]'
+ --crate-file-name'[deprecated in favor of --print-file-name]'
+ --crate-name'[Specify the name of the crate being built]'
--crate-type'[Specify the type of crate to crate]'
+ --debuginfo'[Emit DWARF debug info to the objects created: 0 = no debug info, 1 = line-tables only (for stacktraces and breakpoints), 2 = full debug info with variable and type information (same as -g)]'
+ --dep-info'[Output dependency info to <filename> after compiling]'
+ -g'[Equivalent to --debuginfo=2]'
{-h,--help}'[Display this message]'
-L'[Add a directory to the library search path]'
--linker'[Program to use for linking instead of the default.]'
--parse-only'[Parse only; do not compile, assemble, or link]'
--passes'[Comma or space separated list of pass names to use]'
--pretty'[Pretty-print the input instead of compiling]'
+ --print-crate-name'[Output the crate name and exit]'
+ --print-file-name'[Output the file(s) that would be written if compilation continued and exit]'
--save-temps'[Write intermediate files (.bc, .opt.bc, .o) in addition to normal output]'
--sysroot'[Override the system root]'
--test'[Build a test harness]'
--- /dev/null
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A unique pointer type
+
+use core::any::{Any, AnyRefExt};
+use core::clone::Clone;
+use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
+use core::default::Default;
+use core::fmt;
+use core::intrinsics;
+use core::mem;
+use core::option::Option;
+use core::raw::TraitObject;
+use core::result::{Ok, Err, Result};
+
+/// A value that represents the global exchange heap. This is the default
+/// place that the `box` keyword allocates into when no place is supplied.
+///
+/// The following two examples are equivalent:
+///
+/// use std::boxed::HEAP;
+///
+/// # struct Bar;
+/// # impl Bar { fn new(_a: int) { } }
+/// let foo = box(HEAP) Bar::new(2);
+/// let foo = box Bar::new(2);
+#[lang = "exchange_heap"]
+#[experimental = "may be renamed; uncertain about custom allocator design"]
+pub static HEAP: () = ();
+
+/// A type that represents a uniquely-owned value.
+#[lang = "owned_box"]
+#[unstable = "custom allocators will add an additional type parameter (with default)"]
+pub struct Box<T>(*mut T);
+
+impl<T: Default> Default for Box<T> {
+ fn default() -> Box<T> { box Default::default() }
+}
+
+#[unstable]
+impl<T: Clone> Clone for Box<T> {
+ /// Return a copy of the owned box.
+ #[inline]
+ fn clone(&self) -> Box<T> { box {(**self).clone()} }
+
+ /// Perform copy-assignment from `source` by reusing the existing allocation.
+ #[inline]
+ fn clone_from(&mut self, source: &Box<T>) {
+ (**self).clone_from(&(**source));
+ }
+}
+
+impl<T:PartialEq> PartialEq for Box<T> {
+ #[inline]
+ fn eq(&self, other: &Box<T>) -> bool { *(*self) == *(*other) }
+ #[inline]
+ fn ne(&self, other: &Box<T>) -> bool { *(*self) != *(*other) }
+}
+impl<T:PartialOrd> PartialOrd for Box<T> {
+ #[inline]
+ fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
+ (**self).partial_cmp(*other)
+ }
+ #[inline]
+ fn lt(&self, other: &Box<T>) -> bool { *(*self) < *(*other) }
+ #[inline]
+ fn le(&self, other: &Box<T>) -> bool { *(*self) <= *(*other) }
+ #[inline]
+ fn ge(&self, other: &Box<T>) -> bool { *(*self) >= *(*other) }
+ #[inline]
+ fn gt(&self, other: &Box<T>) -> bool { *(*self) > *(*other) }
+}
+impl<T: Ord> Ord for Box<T> {
+ #[inline]
+ fn cmp(&self, other: &Box<T>) -> Ordering { (**self).cmp(*other) }
+}
+impl<T: Eq> Eq for Box<T> {}
+
+/// Extension methods for an owning `Any` trait object
+#[unstable = "post-DST, the signature of `downcast` will change to take `Box<Self>`"]
+pub trait BoxAny {
+ /// Returns the boxed value if it is of type `T`, or
+ /// `Err(Self)` if it isn't.
+ fn downcast<T: 'static>(self) -> Result<Box<T>, Self>;
+
+ /// Deprecated; this method has been renamed to `downcast`.
+ #[deprecated = "use downcast instead"]
+ fn move<T: 'static>(self) -> Result<Box<T>, Self> {
+ self.downcast::<T>()
+ }
+}
+
+impl BoxAny for Box<Any> {
+ #[inline]
+ fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
+ if self.is::<T>() {
+ unsafe {
+ // Get the raw representation of the trait object
+ let to: TraitObject =
+ *mem::transmute::<&Box<Any>, &TraitObject>(&self);
+
+ // Prevent destructor on self being run
+ intrinsics::forget(self);
+
+ // Extract the data pointer
+ Ok(mem::transmute(to.data))
+ }
+ } else {
+ Err(self)
+ }
+ }
+}
+
+impl<T: fmt::Show> fmt::Show for Box<T> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ (**self).fmt(f)
+ }
+}
+
+impl fmt::Show for Box<Any> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.pad("Box<Any>")
+ }
+}
+
+#[cfg(test)]
+mod test {
+ #[test]
+ fn test_owned_clone() {
+ let a = box 5i;
+ let b: Box<int> = a.clone();
+ assert!(a == b);
+ }
+
+ #[test]
+ fn any_move() {
+ let a = box 8u as Box<Any>;
+ let b = box Test as Box<Any>;
+
+ match a.downcast::<uint>() {
+ Ok(a) => { assert!(a == box 8u); }
+ Err(..) => fail!()
+ }
+ match b.downcast::<Test>() {
+ Ok(a) => { assert!(a == box Test); }
+ Err(..) => fail!()
+ }
+
+ let a = box 8u as Box<Any>;
+ let b = box Test as Box<Any>;
+
+ assert!(a.downcast::<Box<Test>>().is_err());
+ assert!(b.downcast::<Box<uint>>().is_err());
+ }
+
+ #[test]
+ fn test_show() {
+ let a = box 8u as Box<Any>;
+ let b = box Test as Box<Any>;
+ let a_str = a.to_str();
+ let b_str = b.to_str();
+ assert_eq!(a_str.as_slice(), "Box<Any>");
+ assert_eq!(b_str.as_slice(), "Box<Any>");
+
+ let a = &8u as &Any;
+ let b = &Test as &Any;
+ let s = format!("{}", a);
+ assert_eq!(s.as_slice(), "&Any");
+ let s = format!("{}", b);
+ assert_eq!(s.as_slice(), "&Any");
+ }
+}
//!
//! Currently, there are four major definitions in this library.
//!
-//! ## Owned pointers
+//! ## Boxed values
//!
-//! The [`Box`](owned/index.html) type is the core owned pointer type in rust.
+//! The [`Box`](boxed/index.html) type is the core owned pointer type in rust.
//! There can only be one owner of a `Box`, and the owner can decide to mutate
-//! the contents.
+//! the contents, which live on the heap.
//!
//! This type can be sent among tasks efficiently as the size of a `Box` value
//! is just a pointer. Tree-like data structures are often built on owned
//! by libc malloc/free. The `libc_heap` module is defined to be wired up to
//! the system malloc/free.
-#![crate_id = "alloc#0.11.0"]
+#![crate_name = "alloc"]
#![experimental]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#[cfg(test)] #[phase(plugin, link)] extern crate std;
#[cfg(test)] #[phase(plugin, link)] extern crate log;
+// The deprecated name of the boxed module
+
+#[deprecated = "use boxed instead"]
+#[cfg(not(test))]
+pub use owned = boxed;
+
// Heaps provided for low-level allocation strategies
pub mod heap;
// Primitive types using the heaps above
#[cfg(not(test))]
-pub mod owned;
+pub mod boxed;
pub mod arc;
pub mod rc;
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A unique pointer type
-
-use core::any::{Any, AnyRefExt};
-use core::clone::Clone;
-use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
-use core::default::Default;
-use core::fmt;
-use core::intrinsics;
-use core::kinds::Send;
-use core::mem;
-use core::option::Option;
-use core::raw::TraitObject;
-use core::result::{Ok, Err, Result};
-
-/// A value that represents the global exchange heap. This is the default
-/// place that the `box` keyword allocates into when no place is supplied.
-///
-/// The following two examples are equivalent:
-///
-/// use std::owned::HEAP;
-///
-/// # struct Bar;
-/// # impl Bar { fn new(_a: int) { } }
-/// let foo = box(HEAP) Bar::new(2);
-/// let foo = box Bar::new(2);
-#[lang="exchange_heap"]
-pub static HEAP: () = ();
-
-/// A type that represents a uniquely-owned value.
-#[lang="owned_box"]
-pub struct Box<T>(*mut T);
-
-impl<T: Default> Default for Box<T> {
- fn default() -> Box<T> { box Default::default() }
-}
-
-#[unstable]
-impl<T: Clone> Clone for Box<T> {
- /// Return a copy of the owned box.
- #[inline]
- fn clone(&self) -> Box<T> { box {(**self).clone()} }
-
- /// Perform copy-assignment from `source` by reusing the existing allocation.
- #[inline]
- fn clone_from(&mut self, source: &Box<T>) {
- (**self).clone_from(&(**source));
- }
-}
-
-// box pointers
-impl<T:PartialEq> PartialEq for Box<T> {
- #[inline]
- fn eq(&self, other: &Box<T>) -> bool { *(*self) == *(*other) }
- #[inline]
- fn ne(&self, other: &Box<T>) -> bool { *(*self) != *(*other) }
-}
-impl<T:PartialOrd> PartialOrd for Box<T> {
- #[inline]
- fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
- (**self).partial_cmp(*other)
- }
- #[inline]
- fn lt(&self, other: &Box<T>) -> bool { *(*self) < *(*other) }
- #[inline]
- fn le(&self, other: &Box<T>) -> bool { *(*self) <= *(*other) }
- #[inline]
- fn ge(&self, other: &Box<T>) -> bool { *(*self) >= *(*other) }
- #[inline]
- fn gt(&self, other: &Box<T>) -> bool { *(*self) > *(*other) }
-}
-impl<T: Ord> Ord for Box<T> {
- #[inline]
- fn cmp(&self, other: &Box<T>) -> Ordering { (**self).cmp(*other) }
-}
-impl<T: Eq> Eq for Box<T> {}
-
-/// Extension methods for an owning `Any` trait object
-pub trait AnyOwnExt {
- /// Returns the boxed value if it is of type `T`, or
- /// `Err(Self)` if it isn't.
- fn move<T: 'static>(self) -> Result<Box<T>, Self>;
-}
-
-impl AnyOwnExt for Box<Any> {
- #[inline]
- fn move<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
- if self.is::<T>() {
- unsafe {
- // Get the raw representation of the trait object
- let to: TraitObject =
- *mem::transmute::<&Box<Any>, &TraitObject>(&self);
-
- // Prevent destructor on self being run
- intrinsics::forget(self);
-
- // Extract the data pointer
- Ok(mem::transmute(to.data))
- }
- } else {
- Err(self)
- }
- }
-}
-
-/// Extension methods for an owning `Any+Send` trait object
-pub trait AnySendOwnExt {
- /// Returns the boxed value if it is of type `T`, or
- /// `Err(Self)` if it isn't.
- fn move_send<T: 'static>(self) -> Result<Box<T>, Self>;
-}
-
-impl AnySendOwnExt for Box<Any+Send> {
- #[inline]
- fn move_send<T: 'static>(self) -> Result<Box<T>, Box<Any+Send>> {
- if self.is::<T>() {
- unsafe {
- // Get the raw representation of the trait object
- let to: TraitObject =
- *mem::transmute::<&Box<Any+Send>, &TraitObject>(&self);
-
- // Prevent destructor on self being run
- intrinsics::forget(self);
-
- // Extract the data pointer
- Ok(mem::transmute(to.data))
- }
- } else {
- Err(self)
- }
- }
-}
-
-impl<T: fmt::Show> fmt::Show for Box<T> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- (**self).fmt(f)
- }
-}
-
-impl fmt::Show for Box<Any> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.pad("Box<Any>")
- }
-}
-
-#[cfg(test)]
-mod test {
- #[test]
- fn test_owned_clone() {
- let a = box 5i;
- let b: Box<int> = a.clone();
- assert!(a == b);
- }
-
- #[test]
- fn any_move() {
- let a = box 8u as Box<Any>;
- let b = box Test as Box<Any>;
-
- match a.move::<uint>() {
- Ok(a) => { assert!(a == box 8u); }
- Err(..) => fail!()
- }
- match b.move::<Test>() {
- Ok(a) => { assert!(a == box Test); }
- Err(..) => fail!()
- }
-
- let a = box 8u as Box<Any>;
- let b = box Test as Box<Any>;
-
- assert!(a.move::<Box<Test>>().is_err());
- assert!(b.move::<Box<uint>>().is_err());
- }
-
- #[test]
- fn test_show() {
- let a = box 8u as Box<Any>;
- let b = box Test as Box<Any>;
- let a_str = a.to_str();
- let b_str = b.to_str();
- assert_eq!(a_str.as_slice(), "Box<Any>");
- assert_eq!(b_str.as_slice(), "Box<Any>");
-
- let a = &8u as &Any;
- let b = &Test as &Any;
- let s = format!("{}", a);
- assert_eq!(s.as_slice(), "&Any");
- let s = format!("{}", b);
- assert_eq!(s.as_slice(), "&Any");
- }
-}
//! arena but can only hold objects of a single type, and Arena, which is a
//! more complex, slower Arena which can hold objects of any type.
-#![crate_id = "arena#0.11.0"]
+#![crate_name = "arena"]
#![experimental]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+ html_root_url = "http://doc.rust-lang.org/master/")]
#![feature(unsafe_destructor)]
#![allow(missing_doc)]
use core::cmp;
use core::default::Default;
use core::fmt;
-use core::iter::{Enumerate, Repeat, Map, Zip};
-use core::ops;
+use core::iter::Take;
+use core::ops::Index;
use core::slice;
use core::uint;
use std::hash;
use {Collection, Mutable, Set, MutableSet};
use vec::Vec;
+
+static TRUE: bool = true;
+static FALSE: bool = false;
+
#[deriving(Clone)]
struct SmallBitv {
/// only the lowest nbits of this value are used. the rest is undefined.
bits: uint
}
-/// a mask that has a 1 for each defined bit in a small_bitv, assuming n bits
-#[inline]
-fn small_mask(nbits: uint) -> uint {
- (1 << nbits) - 1
-}
-
-impl SmallBitv {
- fn new(bits: uint) -> SmallBitv {
- SmallBitv {bits: bits}
- }
-
- #[inline]
- fn bits_op(&mut self,
- right_bits: uint,
- nbits: uint,
- f: |uint, uint| -> uint)
- -> bool {
- let mask = small_mask(nbits);
- let old_b: uint = self.bits;
- let new_b = f(old_b, right_bits);
- self.bits = new_b;
- mask & old_b != mask & new_b
- }
-
- #[inline]
- fn union(&mut self, s: &SmallBitv, nbits: uint) -> bool {
- self.bits_op(s.bits, nbits, |u1, u2| u1 | u2)
- }
-
- #[inline]
- fn intersect(&mut self, s: &SmallBitv, nbits: uint) -> bool {
- self.bits_op(s.bits, nbits, |u1, u2| u1 & u2)
- }
-
- #[inline]
- fn become(&mut self, s: &SmallBitv, nbits: uint) -> bool {
- self.bits_op(s.bits, nbits, |_u1, u2| u2)
- }
-
- #[inline]
- fn difference(&mut self, s: &SmallBitv, nbits: uint) -> bool {
- self.bits_op(s.bits, nbits, |u1, u2| u1 & !u2)
- }
-
- #[inline]
- fn get(&self, i: uint) -> bool {
- (self.bits & (1 << i)) != 0
- }
-
- #[inline]
- fn set(&mut self, i: uint, x: bool) {
- if x {
- self.bits |= 1<<i;
- }
- else {
- self.bits &= !(1<<i);
- }
- }
-
- #[inline]
- fn equals(&self, b: &SmallBitv, nbits: uint) -> bool {
- let mask = small_mask(nbits);
- mask & self.bits == mask & b.bits
- }
-
- #[inline]
- fn clear(&mut self) { self.bits = 0; }
-
- #[inline]
- fn set_all(&mut self) { self.bits = !0; }
-
- #[inline]
- fn all(&self, nbits: uint) -> bool {
- small_mask(nbits) & !self.bits == 0
- }
-
- #[inline]
- fn none(&self, nbits: uint) -> bool {
- small_mask(nbits) & self.bits == 0
- }
-
- #[inline]
- fn negate(&mut self) { self.bits = !self.bits; }
-}
-
#[deriving(Clone)]
struct BigBitv {
storage: Vec<uint>
}
-/**
- * A mask that has a 1 for each defined bit in the n'th element of a `BigBitv`,
- * assuming n bits.
- */
-#[inline]
-fn big_mask(nbits: uint, elem: uint) -> uint {
- let rmd = nbits % uint::BITS;
- let nelems = nbits/uint::BITS + if rmd == 0 {0} else {1};
-
- if elem < nelems - 1 || rmd == 0 {
- !0
- } else {
- (1 << rmd) - 1
- }
-}
-
-impl BigBitv {
- fn new(storage: Vec<uint>) -> BigBitv {
- BigBitv {storage: storage}
- }
-
- #[inline]
- fn process(&mut self,
- b: &BigBitv,
- nbits: uint,
- op: |uint, uint| -> uint)
- -> bool {
- let len = b.storage.len();
- assert_eq!(self.storage.len(), len);
- let mut changed = false;
- for (i, (a, b)) in self.storage.mut_iter()
- .zip(b.storage.iter())
- .enumerate() {
- let mask = big_mask(nbits, i);
- let w0 = *a & mask;
- let w1 = *b & mask;
- let w = op(w0, w1) & mask;
- if w0 != w {
- changed = true;
- *a = w;
- }
- }
- changed
- }
-
- #[inline]
- fn each_storage(&mut self, op: |v: &mut uint| -> bool) -> bool {
- self.storage.mut_iter().advance(|elt| op(elt))
- }
-
- #[inline]
- fn negate(&mut self) {
- self.each_storage(|w| { *w = !*w; true });
- }
-
- #[inline]
- fn union(&mut self, b: &BigBitv, nbits: uint) -> bool {
- self.process(b, nbits, |w1, w2| w1 | w2)
- }
-
- #[inline]
- fn intersect(&mut self, b: &BigBitv, nbits: uint) -> bool {
- self.process(b, nbits, |w1, w2| w1 & w2)
- }
-
- #[inline]
- fn become(&mut self, b: &BigBitv, nbits: uint) -> bool {
- self.process(b, nbits, |_, w| w)
- }
-
- #[inline]
- fn difference(&mut self, b: &BigBitv, nbits: uint) -> bool {
- self.process(b, nbits, |w1, w2| w1 & !w2)
- }
-
- #[inline]
- fn get(&self, i: uint) -> bool {
- let w = i / uint::BITS;
- let b = i % uint::BITS;
- let x = 1 & self.storage.get(w) >> b;
- x == 1
- }
-
- #[inline]
- fn set(&mut self, i: uint, x: bool) {
- let w = i / uint::BITS;
- let b = i % uint::BITS;
- let flag = 1 << b;
- *self.storage.get_mut(w) = if x { *self.storage.get(w) | flag }
- else { *self.storage.get(w) & !flag };
- }
-
- #[inline]
- fn equals(&self, b: &BigBitv, nbits: uint) -> bool {
- for (i, elt) in b.storage.iter().enumerate() {
- let mask = big_mask(nbits, i);
- if mask & *self.storage.get(i) != mask & *elt {
- return false;
- }
- }
- true
- }
-}
-
#[deriving(Clone)]
enum BitvVariant { Big(BigBitv), Small(SmallBitv) }
-enum Op {Union, Intersect, Assign, Difference}
-
/// The bitvector type
///
/// # Example
/// ```rust
/// use collections::bitv::Bitv;
///
-/// let mut bv = Bitv::new(10, false);
+/// let mut bv = Bitv::with_capacity(10, false);
///
/// // insert all primes less than 10
/// bv.set(2, true);
/// bv.set(3, true);
/// bv.set(5, true);
/// bv.set(7, true);
-/// println!("{}", bv.to_str());
+/// println!("{}", bv.to_string());
/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
///
/// // flip all values in bitvector, producing non-primes less than 10
/// bv.negate();
-/// println!("{}", bv.to_str());
+/// println!("{}", bv.to_string());
/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
///
/// // reset bitvector to empty
/// bv.clear();
-/// println!("{}", bv.to_str());
+/// println!("{}", bv.to_string());
/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
/// ```
-#[deriving(Clone)]
pub struct Bitv {
- /// Internal representation of the bit vector (small or large)
- rep: BitvVariant,
+ /// Internal representation of the bit vector
+ storage: Vec<uint>,
/// The number of valid bits in the internal representation
nbits: uint
}
-fn die() -> ! {
- fail!("Tried to do operation on bit vectors with different sizes");
+impl Index<uint,bool> for Bitv {
+ #[inline]
+ fn index<'a>(&'a self, i: &uint) -> &'a bool {
+ if self.get(*i) {
+ &TRUE
+ } else {
+ &FALSE
+ }
+ }
}
-impl Bitv {
+struct MaskWords<'a> {
+ iter: slice::Items<'a, uint>,
+ next_word: Option<&'a uint>,
+ last_word_mask: uint,
+ offset: uint
+}
+
+impl<'a> Iterator<(uint, uint)> for MaskWords<'a> {
+ /// Returns (offset, word)
#[inline]
- fn do_op(&mut self, op: Op, other: &Bitv) -> bool {
- if self.nbits != other.nbits {
- die();
- }
- match self.rep {
- Small(ref mut s) => match other.rep {
- Small(ref s1) => match op {
- Union => s.union(s1, self.nbits),
- Intersect => s.intersect(s1, self.nbits),
- Assign => s.become(s1, self.nbits),
- Difference => s.difference(s1, self.nbits)
+ fn next<'a>(&'a mut self) -> Option<(uint, uint)> {
+ let ret = self.next_word;
+ match ret {
+ Some(&w) => {
+ self.next_word = self.iter.next();
+ self.offset += 1;
+ // The last word may need to be masked
+ if self.next_word.is_none() {
+ Some((self.offset - 1, w & self.last_word_mask))
+ } else {
+ Some((self.offset - 1, w))
+ }
},
- Big(_) => die()
- },
- Big(ref mut s) => match other.rep {
- Small(_) => die(),
- Big(ref s1) => match op {
- Union => s.union(s1, self.nbits),
- Intersect => s.intersect(s1, self.nbits),
- Assign => s.become(s1, self.nbits),
- Difference => s.difference(s1, self.nbits)
- }
- }
+ None => None
}
}
}
impl Bitv {
- /// Creates an empty Bitv that holds `nbits` elements, setting each element
+ #[inline]
+ fn process(&mut self, other: &Bitv, op: |uint, uint| -> uint) -> bool {
+ let len = other.storage.len();
+ assert_eq!(self.storage.len(), len);
+ let mut changed = false;
+ // Notice: `a` is *not* masked here, which is fine as long as
+ // `op` is a bitwise operation, since any bits that should've
+ // been masked were fine to change anyway. `b` is masked to
+ // make sure its unmasked bits do not cause damage.
+ for (a, (_, b)) in self.storage.mut_iter()
+ .zip(other.mask_words(0)) {
+ let w = op(*a, b);
+ if *a != w {
+ changed = true;
+ *a = w;
+ }
+ }
+ changed
+ }
+
+ #[inline]
+ fn mask_words<'a>(&'a self, mut start: uint) -> MaskWords<'a> {
+ if start > self.storage.len() {
+ start = self.storage.len();
+ }
+ let mut iter = self.storage.slice_from(start).iter();
+ MaskWords {
+ next_word: iter.next(),
+ iter: iter,
+ last_word_mask: {
+ let rem = self.nbits % uint::BITS;
+ if rem > 0 {
+ (1 << rem) - 1
+ } else { !0 }
+ },
+ offset: start
+ }
+ }
+
+ /// Creates an empty Bitv
+ pub fn new() -> Bitv {
+ Bitv { storage: Vec::new(), nbits: 0 }
+ }
+
+ /// Creates a Bitv that holds `nbits` elements, setting each element
/// to `init`.
- pub fn new(nbits: uint, init: bool) -> Bitv {
- let rep = if nbits < uint::BITS {
- Small(SmallBitv::new(if init {(1<<nbits)-1} else {0}))
- } else if nbits == uint::BITS {
- Small(SmallBitv::new(if init {!0} else {0}))
- } else {
- let exact = nbits % uint::BITS == 0;
- let nelems = nbits/uint::BITS + if exact {0} else {1};
- let s =
- if init {
- if exact {
- Vec::from_elem(nelems, !0u)
- } else {
- let mut v = Vec::from_elem(nelems-1, !0u);
- v.push((1<<nbits % uint::BITS)-1);
- v
- }
- } else { Vec::from_elem(nelems, 0u)};
- Big(BigBitv::new(s))
- };
- Bitv {rep: rep, nbits: nbits}
+ pub fn with_capacity(nbits: uint, init: bool) -> Bitv {
+ Bitv {
+ storage: Vec::from_elem((nbits + uint::BITS - 1) / uint::BITS,
+ if init { !0u } else { 0u }),
+ nbits: nbits
+ }
}
/**
* the same length. Returns `true` if `self` changed.
*/
#[inline]
- pub fn union(&mut self, v1: &Bitv) -> bool { self.do_op(Union, v1) }
+ pub fn union(&mut self, other: &Bitv) -> bool {
+ self.process(other, |w1, w2| w1 | w2)
+ }
/**
* Calculates the intersection of two bitvectors
* must be the same length. Returns `true` if `self` changed.
*/
#[inline]
- pub fn intersect(&mut self, v1: &Bitv) -> bool {
- self.do_op(Intersect, v1)
+ pub fn intersect(&mut self, other: &Bitv) -> bool {
+ self.process(other, |w1, w2| w1 & w2)
}
- /**
- * Assigns the value of `v1` to `self`
- *
- * Both bitvectors must be the same length. Returns `true` if `self` was
- * changed
- */
- #[inline]
- pub fn assign(&mut self, v: &Bitv) -> bool { self.do_op(Assign, v) }
-
/// Retrieve the value at index `i`
#[inline]
pub fn get(&self, i: uint) -> bool {
- assert!((i < self.nbits));
- match self.rep {
- Big(ref b) => b.get(i),
- Small(ref s) => s.get(i)
- }
+ assert!(i < self.nbits);
+ let w = i / uint::BITS;
+ let b = i % uint::BITS;
+ let x = self.storage.get(w) & (1 << b);
+ x != 0
}
/**
*/
#[inline]
pub fn set(&mut self, i: uint, x: bool) {
- assert!((i < self.nbits));
- match self.rep {
- Big(ref mut b) => b.set(i, x),
- Small(ref mut s) => s.set(i, x)
- }
- }
-
- /// Set all bits to 0
- #[inline]
- pub fn clear(&mut self) {
- match self.rep {
- Small(ref mut b) => b.clear(),
- Big(ref mut s) => {
- s.each_storage(|w| { *w = 0u; true });
- }
- }
+ assert!(i < self.nbits);
+ let w = i / uint::BITS;
+ let b = i % uint::BITS;
+ let flag = 1 << b;
+ *self.storage.get_mut(w) = if x { *self.storage.get(w) | flag }
+ else { *self.storage.get(w) & !flag };
}
/// Set all bits to 1
#[inline]
pub fn set_all(&mut self) {
- match self.rep {
- Small(ref mut b) => b.set_all(),
- Big(ref mut s) => {
- s.each_storage(|w| { *w = !0u; true });
- }
- }
+ for w in self.storage.mut_iter() { *w = !0u; }
}
/// Flip all bits
#[inline]
pub fn negate(&mut self) {
- match self.rep {
- Small(ref mut s) => s.negate(),
- Big(ref mut b) => b.negate(),
- }
+ for w in self.storage.mut_iter() { *w = !*w; }
}
/**
* Returns `true` if `v0` was changed.
*/
#[inline]
- pub fn difference(&mut self, v: &Bitv) -> bool {
- self.do_op(Difference, v)
+ pub fn difference(&mut self, other: &Bitv) -> bool {
+ self.process(other, |w1, w2| w1 & !w2)
}
/// Returns `true` if all bits are 1
#[inline]
pub fn all(&self) -> bool {
- match self.rep {
- Small(ref b) => b.all(self.nbits),
- _ => self.iter().all(|x| x)
- }
+ let mut last_word = !0u;
+ // Check that every word but the last is all-ones...
+ self.mask_words(0).all(|(_, elem)|
+ { let tmp = last_word; last_word = elem; tmp == !0u }) &&
+ // ...and that the last word is ones as far as it needs to be
+ (last_word == ((1 << self.nbits % uint::BITS) - 1) || last_word == !0u)
}
/// Returns an iterator over the elements of the vector in order.
///
/// ```rust
/// use collections::bitv::Bitv;
- /// let mut bv = Bitv::new(10, false);
+ /// let mut bv = Bitv::with_capacity(10, false);
/// bv.set(1, true);
/// bv.set(2, true);
/// bv.set(3, true);
/// Returns `true` if all bits are 0
pub fn none(&self) -> bool {
- match self.rep {
- Small(ref b) => b.none(self.nbits),
- _ => self.iter().all(|x| !x)
- }
+ self.mask_words(0).all(|(_, w)| w == 0)
}
#[inline]
!self.none()
}
- /**
- * Converts `self` to a vector of `uint` with the same length.
- *
- * Each `uint` in the resulting vector has either value `0u` or `1u`.
- */
- pub fn to_vec(&self) -> Vec<uint> {
- Vec::from_fn(self.nbits, |i| if self.get(i) { 1 } else { 0 })
- }
-
/**
* Organise the bits into bytes, such that the first bit in the
* `Bitv` becomes the high-order bit of the first byte. If the
if offset >= bitv.nbits {
0
} else {
- bitv[offset] as u8 << (7 - bit)
+ bitv.get(offset) as u8 << (7 - bit)
}
}
* Transform `self` into a `Vec<bool>` by turning each bit into a `bool`.
*/
pub fn to_bools(&self) -> Vec<bool> {
- Vec::from_fn(self.nbits, |i| self[i])
+ Vec::from_fn(self.nbits, |i| self.get(i))
}
/**
true
}
- pub fn ones(&self, f: |uint| -> bool) -> bool {
- range(0u, self.nbits).advance(|i| !self.get(i) || f(i))
+ /// Shorten a Bitv, dropping excess elements.
+ ///
+ /// If `len` is greater than the vector's current length, this has no
+ /// effect.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use collections::bitv::Bitv;
+ /// let mut bvec: Bitv = vec![false, true, true, false].iter().map(|n| *n).collect();
+ /// let expected: Bitv = vec![false, true].iter().map(|n| *n).collect();
+ /// bvec.truncate(2);
+ /// assert_eq!(bvec, expected);
+ /// ```
+ pub fn truncate(&mut self, len: uint) {
+ if len < self.len() {
+ self.nbits = len;
+ let word_len = (len + uint::BITS - 1) / uint::BITS;
+ self.storage.truncate(word_len);
+ if len % uint::BITS > 0 {
+ let mask = (1 << len % uint::BITS) - 1;
+ *self.storage.get_mut(word_len - 1) &= mask;
+ }
+ }
+ }
+
+ /// Grows the vector to be able to store `size` bits without resizing
+ pub fn reserve(&mut self, size: uint) {
+ let old_size = self.storage.len();
+ let size = (size + uint::BITS - 1) / uint::BITS;
+ if old_size < size {
+ self.storage.grow(size - old_size, &0);
+ }
+ }
+
+ /// Returns the capacity in bits for this bit vector. Inserting any
+ /// element less than this amount will not trigger a resizing.
+ #[inline]
+ pub fn capacity(&self) -> uint {
+ self.storage.len() * uint::BITS
}
+ /// Grows the `Bitv` in-place.
+ ///
+ /// Adds `n` copies of `value` to the `Bitv`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use collections::bitv::Bitv;
+ /// let mut bvec: Bitv = vec![false, true, true, false].iter().map(|n| *n).collect();
+ /// bvec.grow(2, true);
+ /// assert_eq!(bvec, vec![false, true, true, false, true, true].iter().map(|n| *n).collect());
+ /// ```
+ pub fn grow(&mut self, n: uint, value: bool) {
+ let new_nbits = self.nbits + n;
+ let new_nwords = (new_nbits + uint::BITS - 1) / uint::BITS;
+ let full_value = if value { !0 } else { 0 };
+ // Correct the old tail word
+ let old_last_word = (self.nbits + uint::BITS - 1) / uint::BITS - 1;
+ if self.nbits % uint::BITS > 0 {
+ let overhang = self.nbits % uint::BITS; // # of already-used bits
+ let mask = !((1 << overhang) - 1); // e.g. 5 unused bits => 111110....0
+ if value {
+ *self.storage.get_mut(old_last_word) |= mask;
+ } else {
+ *self.storage.get_mut(old_last_word) &= !mask;
+ }
+ }
+ // Fill in words after the old tail word
+ let stop_idx = cmp::min(self.storage.len(), new_nwords);
+ for idx in range(old_last_word + 1, stop_idx) {
+ *self.storage.get_mut(idx) = full_value;
+ }
+ // Allocate new words, if needed
+ if new_nwords > self.storage.len() {
+ let to_add = new_nwords - self.storage.len();
+ self.storage.grow(to_add, &full_value);
+ }
+ // Adjust internal bit count
+ self.nbits = new_nbits;
+ }
+
+ /// Shorten a `Bitv` by one, returning the removed element
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use collections::bitv::Bitv;
+ /// let mut bvec: Bitv = vec![false, true, true, false].iter().map(|n| *n).collect();
+ /// let expected: Bitv = vec![false, true, true].iter().map(|n| *n).collect();
+ /// let popped = bvec.pop();
+ /// assert_eq!(popped, false);
+ /// assert_eq!(bvec, expected);
+ /// ```
+ pub fn pop(&mut self) -> bool {
+ let ret = self.get(self.nbits - 1);
+ // If we are unusing a whole word, make sure it is zeroed out
+ if self.nbits % uint::BITS == 1 {
+ *self.storage.get_mut(self.nbits / uint::BITS) = 0;
+ }
+ self.nbits -= 1;
+ ret
+ }
+
+ /// Pushes a `bool` onto the `Bitv`
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use collections::bitv::Bitv;
+ /// let prototype: Bitv = vec![false, true, true, false].iter().map(|n| *n).collect();
+ /// let mut bvec: Bitv = vec![false, true].iter().map(|n| *n).collect();
+ /// bvec.push(true);
+ /// bvec.push(false);
+ /// assert_eq!(prototype, bvec);
+ /// ```
+ pub fn push(&mut self, elem: bool) {
+ let insert_pos = self.nbits;
+ self.nbits += 1;
+ if self.storage.len() * uint::BITS < self.nbits {
+ self.storage.push(0);
+ }
+ self.set(insert_pos, elem);
+ }
}
/**
})
}
-/**
- * Transform a `[bool]` into a `Bitv` by converting each `bool` into a bit.
- */
-pub fn from_bools(bools: &[bool]) -> Bitv {
- from_fn(bools.len(), |i| bools[i])
-}
-
/**
* Create a `Bitv` of the specified length where the value at each
* index is `f(index)`.
*/
pub fn from_fn(len: uint, f: |index: uint| -> bool) -> Bitv {
- let mut bitv = Bitv::new(len, false);
+ let mut bitv = Bitv::with_capacity(len, false);
for i in range(0u, len) {
bitv.set(i, f(i));
}
bitv
}
-impl ops::Index<uint,bool> for Bitv {
- fn index(&self, i: &uint) -> bool {
- self.get(*i)
+impl Default for Bitv {
+ #[inline]
+ fn default() -> Bitv { Bitv::new() }
+}
+
+impl Collection for Bitv {
+ #[inline]
+ fn len(&self) -> uint { self.nbits }
+}
+
+impl Mutable for Bitv {
+ #[inline]
+ fn clear(&mut self) {
+ for w in self.storage.mut_iter() { *w = 0u; }
+ }
+}
+
+impl FromIterator<bool> for Bitv {
+ fn from_iter<I:Iterator<bool>>(iterator: I) -> Bitv {
+ let mut ret = Bitv::new();
+ ret.extend(iterator);
+ ret
+ }
+}
+
+impl Extendable<bool> for Bitv {
+ #[inline]
+ fn extend<I: Iterator<bool>>(&mut self, mut iterator: I) {
+ let (min, _) = iterator.size_hint();
+ let nbits = self.nbits;
+ self.reserve(nbits + min);
+ for element in iterator {
+ self.push(element)
+ }
+ }
+}
+
+impl Clone for Bitv {
+ #[inline]
+ fn clone(&self) -> Bitv {
+ Bitv { storage: self.storage.clone(), nbits: self.nbits }
+ }
+
+ #[inline]
+ fn clone_from(&mut self, source: &Bitv) {
+ self.nbits = source.nbits;
+ self.storage.reserve(source.storage.len());
+ for (i, w) in self.storage.mut_iter().enumerate() { *w = *source.storage.get(i); }
}
}
impl<S: hash::Writer> hash::Hash<S> for Bitv {
fn hash(&self, state: &mut S) {
self.nbits.hash(state);
- match self.rep {
- Small(ref s) => (s.bits & small_mask(self.nbits)).hash(state),
- Big(ref b) => {
- for (i, ele) in b.storage.iter().enumerate() {
- (ele & big_mask(self.nbits, i)).hash(state);
- }
- }
+ for (_, elem) in self.mask_words(0) {
+ elem.hash(state);
}
}
}
impl cmp::PartialEq for Bitv {
#[inline]
fn eq(&self, other: &Bitv) -> bool {
- if self.nbits != other.nbits { return false; }
- match self.rep {
- Small(ref b) => match other.rep {
- Small(ref b1) => b.equals(b1, self.nbits),
- _ => false
- },
- Big(ref s) => match other.rep {
- Big(ref s1) => s.equals(s1, self.nbits),
- Small(_) => return false
- }
+ if self.nbits != other.nbits {
+ return false;
}
+ self.mask_words(0).zip(other.mask_words(0)).all(|((_, w1), (_, w2))| w1 == w2)
}
}
impl cmp::Eq for Bitv {}
-#[inline]
-fn iterate_bits(base: uint, bits: uint, f: |uint| -> bool) -> bool {
- if bits == 0 {
- return true;
- }
- for i in range(0u, uint::BITS) {
- if bits & (1 << i) != 0 {
- if !f(base + i) {
- return false;
- }
- }
- }
- return true;
-}
-
/// An iterator for `Bitv`.
pub struct Bits<'a> {
bitv: &'a Bitv,
/// It should also be noted that the amount of storage necessary for holding a
/// set of objects is proportional to the maximum of the objects when viewed
/// as a `uint`.
-#[deriving(Clone)]
-pub struct BitvSet {
- size: uint,
-
- // In theory this is a `Bitv` instead of always a `BigBitv`, but knowing that
- // there's an array of storage makes our lives a whole lot easier when
- // performing union/intersection/etc operations
- bitv: BigBitv
-}
+#[deriving(Clone, PartialEq, Eq)]
+pub struct BitvSet(Bitv);
impl Default for BitvSet {
#[inline]
impl BitvSet {
/// Creates a new bit vector set with initially no contents
+ #[inline]
pub fn new() -> BitvSet {
- BitvSet{ size: 0, bitv: BigBitv::new(vec!(0)) }
+ BitvSet(Bitv::new())
+ }
+
+ /// Creates a new bit vector set with initially no contents, able to
+ /// hold `nbits` elements without resizing
+ #[inline]
+ pub fn with_capacity(nbits: uint) -> BitvSet {
+ BitvSet(Bitv::with_capacity(nbits, false))
}
/// Creates a new bit vector set from the given bit vector
+ #[inline]
pub fn from_bitv(bitv: Bitv) -> BitvSet {
- let mut size = 0;
- bitv.ones(|_| {
- size += 1;
- true
- });
- let Bitv{rep, ..} = bitv;
- match rep {
- Big(b) => BitvSet{ size: size, bitv: b },
- Small(SmallBitv{bits}) =>
- BitvSet{ size: size, bitv: BigBitv{ storage: vec!(bits) } },
- }
+ BitvSet(bitv)
}
/// Returns the capacity in bits for this bit vector. Inserting any
/// element less than this amount will not trigger a resizing.
- pub fn capacity(&self) -> uint { self.bitv.storage.len() * uint::BITS }
+ #[inline]
+ pub fn capacity(&self) -> uint {
+ let &BitvSet(ref bitv) = self;
+ bitv.capacity()
+ }
+
+ /// Grows the underlying vector to be able to store `size` bits
+ pub fn reserve(&mut self, size: uint) {
+ let &BitvSet(ref mut bitv) = self;
+ bitv.reserve(size)
+ }
/// Consumes this set to return the underlying bit vector
+ #[inline]
pub fn unwrap(self) -> Bitv {
- let cap = self.capacity();
- let BitvSet{bitv, ..} = self;
- return Bitv{ nbits:cap, rep: Big(bitv) };
+ let BitvSet(bitv) = self;
+ bitv
+ }
+
+ /// Returns a reference to the underlying bit vector
+ #[inline]
+ pub fn get_ref<'a>(&'a self) -> &'a Bitv {
+ let &BitvSet(ref bitv) = self;
+ bitv
+ }
+
+ /// Returns a mutable reference to the underlying bit vector
+ #[inline]
+ pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut Bitv {
+ let &BitvSet(ref mut bitv) = self;
+ bitv
}
#[inline]
fn other_op(&mut self, other: &BitvSet, f: |uint, uint| -> uint) {
- fn nbits(mut w: uint) -> uint {
- let mut bits = 0;
- for _ in range(0u, uint::BITS) {
- if w == 0 {
- break;
- }
- bits += w & 1;
- w >>= 1;
- }
- return bits;
- }
- if self.capacity() < other.capacity() {
- self.bitv.storage.grow(other.capacity() / uint::BITS, &0);
- }
- for (i, &w) in other.bitv.storage.iter().enumerate() {
- let old = *self.bitv.storage.get(i);
+ // Unwrap Bitvs
+ let &BitvSet(ref mut self_bitv) = self;
+ let &BitvSet(ref other_bitv) = other;
+ // Expand the vector if necessary
+ self_bitv.reserve(other_bitv.capacity());
+ // Apply values
+ for (i, w) in other_bitv.mask_words(0) {
+ let old = *self_bitv.storage.get(i);
let new = f(old, w);
- *self.bitv.storage.get_mut(i) = new;
- self.size += nbits(new) - nbits(old);
+ *self_bitv.storage.get_mut(i) = new;
}
}
+ #[inline]
+ /// Truncate the underlying vector to the least length required
+ pub fn shrink_to_fit(&mut self) {
+ let &BitvSet(ref mut bitv) = self;
+ // Obtain original length
+ let old_len = bitv.storage.len();
+ // Obtain coarse trailing zero length
+ let n = bitv.storage.iter().rev().take_while(|&&n| n == 0).count();
+ // Truncate
+ let trunc_len = cmp::max(old_len - n, 1);
+ bitv.storage.truncate(trunc_len);
+ bitv.nbits = trunc_len * uint::BITS;
+ }
+
/// Union in-place with the specified other bit vector
+ #[inline]
pub fn union_with(&mut self, other: &BitvSet) {
self.other_op(other, |w1, w2| w1 | w2);
}
/// Intersect in-place with the specified other bit vector
+ #[inline]
pub fn intersect_with(&mut self, other: &BitvSet) {
self.other_op(other, |w1, w2| w1 & w2);
}
/// Difference in-place with the specified other bit vector
+ #[inline]
pub fn difference_with(&mut self, other: &BitvSet) {
self.other_op(other, |w1, w2| w1 & !w2);
}
/// Symmetric difference in-place with the specified other bit vector
+ #[inline]
pub fn symmetric_difference_with(&mut self, other: &BitvSet) {
self.other_op(other, |w1, w2| w1 ^ w2);
}
+ /// Iterator over each uint stored in the BitvSet
+ #[inline]
pub fn iter<'a>(&'a self) -> BitPositions<'a> {
BitPositions {set: self, next_idx: 0}
}
- pub fn difference(&self, other: &BitvSet, f: |&uint| -> bool) -> bool {
- for (i, w1, w2) in self.commons(other) {
- if !iterate_bits(i, w1 & !w2, |b| f(&b)) {
- return false
- }
- };
- /* everything we have that they don't also shows up */
- self.outliers(other).advance(|(mine, i, w)|
- !mine || iterate_bits(i, w, |b| f(&b))
- )
- }
-
- pub fn symmetric_difference(&self, other: &BitvSet, f: |&uint| -> bool)
- -> bool {
- for (i, w1, w2) in self.commons(other) {
- if !iterate_bits(i, w1 ^ w2, |b| f(&b)) {
- return false
- }
- };
- self.outliers(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b)))
- }
-
- pub fn intersection(&self, other: &BitvSet, f: |&uint| -> bool) -> bool {
- self.commons(other).advance(|(i, w1, w2)| iterate_bits(i, w1 & w2, |b| f(&b)))
+ /// Iterator over each uint stored in the `self` setminus `other`
+ #[inline]
+ pub fn difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+ TwoBitPositions {
+ set: self,
+ other: other,
+ merge: |w1, w2| w1 & !w2,
+ current_word: 0,
+ next_idx: 0
+ }
}
- pub fn union(&self, other: &BitvSet, f: |&uint| -> bool) -> bool {
- for (i, w1, w2) in self.commons(other) {
- if !iterate_bits(i, w1 | w2, |b| f(&b)) {
- return false
- }
- };
- self.outliers(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b)))
+ /// Iterator over each uint stored in the symmetric difference of `self` and `other`
+ #[inline]
+ pub fn symmetric_difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+ TwoBitPositions {
+ set: self,
+ other: other,
+ merge: |w1, w2| w1 ^ w2,
+ current_word: 0,
+ next_idx: 0
+ }
}
-}
-impl cmp::PartialEq for BitvSet {
- fn eq(&self, other: &BitvSet) -> bool {
- if self.size != other.size {
- return false;
- }
- for (_, w1, w2) in self.commons(other) {
- if w1 != w2 {
- return false;
- }
- }
- for (_, _, w) in self.outliers(other) {
- if w != 0 {
- return false;
- }
+ /// Iterator over each uint stored in `self` intersect `other`
+ #[inline]
+ pub fn intersection<'a>(&'a self, other: &'a BitvSet) -> Take<TwoBitPositions<'a>> {
+ let min = cmp::min(self.capacity(), other.capacity());
+ TwoBitPositions {
+ set: self,
+ other: other,
+ merge: |w1, w2| w1 & w2,
+ current_word: 0,
+ next_idx: 0
+ }.take(min)
+ }
+
+ /// Iterator over each uint stored in `self` union `other`
+ #[inline]
+ pub fn union<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
+ TwoBitPositions {
+ set: self,
+ other: other,
+ merge: |w1, w2| w1 | w2,
+ current_word: 0,
+ next_idx: 0
}
- return true;
}
-
- fn ne(&self, other: &BitvSet) -> bool { !self.eq(other) }
}
-impl cmp::Eq for BitvSet {}
-
impl fmt::Show for BitvSet {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
try!(write!(fmt, "{{"));
impl Collection for BitvSet {
#[inline]
- fn len(&self) -> uint { self.size }
+ fn len(&self) -> uint {
+ let &BitvSet(ref bitv) = self;
+ bitv.storage.iter().fold(0, |acc, &n| acc + n.count_ones())
+ }
}
impl Mutable for BitvSet {
+ #[inline]
fn clear(&mut self) {
- self.bitv.each_storage(|w| { *w = 0; true });
- self.size = 0;
+ let &BitvSet(ref mut bitv) = self;
+ bitv.clear();
}
}
impl Set<uint> for BitvSet {
+ #[inline]
fn contains(&self, value: &uint) -> bool {
- *value < self.bitv.storage.len() * uint::BITS && self.bitv.get(*value)
+ let &BitvSet(ref bitv) = self;
+ *value < bitv.nbits && bitv.get(*value)
}
+ #[inline]
fn is_disjoint(&self, other: &BitvSet) -> bool {
- self.intersection(other, |_| false)
+ self.intersection(other).count() > 0
}
+ #[inline]
fn is_subset(&self, other: &BitvSet) -> bool {
- for (_, w1, w2) in self.commons(other) {
- if w1 & w2 != w1 {
- return false;
- }
- }
- /* If anything is not ours, then everything is not ours so we're
- definitely a subset in that case. Otherwise if there's any stray
- ones that 'other' doesn't have, we're not a subset. */
- for (mine, _, w) in self.outliers(other) {
- if !mine {
- return true;
- } else if w != 0 {
- return false;
- }
- }
- return true;
+ let &BitvSet(ref self_bitv) = self;
+ let &BitvSet(ref other_bitv) = other;
+
+ // Check that `self` intersect `other` is self
+ self_bitv.mask_words(0).zip(other_bitv.mask_words(0))
+ .all(|((_, w1), (_, w2))| w1 & w2 == w1) &&
+ // Check that `self` setminus `other` is empty
+ self_bitv.mask_words(other_bitv.storage.len()).all(|(_, w)| w == 0)
}
+ #[inline]
fn is_superset(&self, other: &BitvSet) -> bool {
other.is_subset(self)
}
if self.contains(&value) {
return false;
}
- let nbits = self.capacity();
- if value >= nbits {
- let newsize = cmp::max(value, nbits * 2) / uint::BITS + 1;
- assert!(newsize > self.bitv.storage.len());
- self.bitv.storage.grow(newsize, &0);
+ if value >= self.capacity() {
+ let new_cap = cmp::max(value + 1, self.capacity() * 2);
+ self.reserve(new_cap);
+ }
+ let &BitvSet(ref mut bitv) = self;
+ if value >= bitv.nbits {
+ // If we are increasing nbits, make sure we mask out any previously-unconsidered bits
+ let old_rem = bitv.nbits % uint::BITS;
+ if old_rem != 0 {
+ let old_last_word = (bitv.nbits + uint::BITS - 1) / uint::BITS - 1;
+ *bitv.storage.get_mut(old_last_word) &= (1 << old_rem) - 1;
+ }
+ bitv.nbits = value + 1;
}
- self.size += 1;
- self.bitv.set(value, true);
+ bitv.set(value, true);
return true;
}
if !self.contains(value) {
return false;
}
- self.size -= 1;
- self.bitv.set(*value, false);
-
- // Attempt to truncate our storage
- let mut i = self.bitv.storage.len();
- while i > 1 && *self.bitv.storage.get(i - 1) == 0 {
- i -= 1;
- }
- self.bitv.storage.truncate(i);
-
+ let &BitvSet(ref mut bitv) = self;
+ bitv.set(*value, false);
return true;
}
}
-impl BitvSet {
- /// Visits each of the words that the two bit vectors (`self` and `other`)
- /// both have in common. The three yielded arguments are (bit location,
- /// w1, w2) where the bit location is the number of bits offset so far,
- /// and w1/w2 are the words coming from the two vectors self, other.
- fn commons<'a>(&'a self, other: &'a BitvSet)
- -> Map<'static, ((uint, &'a uint), &'a Vec<uint>), (uint, uint, uint),
- Zip<Enumerate<slice::Items<'a, uint>>, Repeat<&'a Vec<uint>>>> {
- let min = cmp::min(self.bitv.storage.len(), other.bitv.storage.len());
- self.bitv.storage.slice(0, min).iter().enumerate()
- .zip(Repeat::new(&other.bitv.storage))
- .map(|((i, &w), o_store)| (i * uint::BITS, w, *o_store.get(i)))
- }
-
- /// Visits each word in `self` or `other` that extends beyond the other. This
- /// will only iterate through one of the vectors, and it only iterates
- /// over the portion that doesn't overlap with the other one.
- ///
- /// The yielded arguments are a `bool`, the bit offset, and a word. The `bool`
- /// is true if the word comes from `self`, and `false` if it comes from
- /// `other`.
- fn outliers<'a>(&'a self, other: &'a BitvSet)
- -> Map<'static, ((uint, &'a uint), uint), (bool, uint, uint),
- Zip<Enumerate<slice::Items<'a, uint>>, Repeat<uint>>> {
- let slen = self.bitv.storage.len();
- let olen = other.bitv.storage.len();
-
- if olen < slen {
- self.bitv.storage.slice_from(olen).iter().enumerate()
- .zip(Repeat::new(olen))
- .map(|((i, &w), min)| (true, (i + min) * uint::BITS, w))
- } else {
- other.bitv.storage.slice_from(slen).iter().enumerate()
- .zip(Repeat::new(slen))
- .map(|((i, &w), min)| (false, (i + min) * uint::BITS, w))
- }
- }
+pub struct BitPositions<'a> {
+ set: &'a BitvSet,
+ next_idx: uint
}
-pub struct BitPositions<'a> {
+pub struct TwoBitPositions<'a> {
set: &'a BitvSet,
+ other: &'a BitvSet,
+ merge: |uint, uint|: 'a -> uint,
+ current_word: uint,
next_idx: uint
}
impl<'a> Iterator<uint> for BitPositions<'a> {
- #[inline]
fn next(&mut self) -> Option<uint> {
while self.next_idx < self.set.capacity() {
let idx = self.next_idx;
return None;
}
+ #[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
(0, Some(self.set.capacity() - self.next_idx))
}
}
+impl<'a> Iterator<uint> for TwoBitPositions<'a> {
+ fn next(&mut self) -> Option<uint> {
+ while self.next_idx < self.set.capacity() ||
+ self.next_idx < self.other.capacity() {
+ let bit_idx = self.next_idx % uint::BITS;
+ if bit_idx == 0 {
+ let &BitvSet(ref s_bitv) = self.set;
+ let &BitvSet(ref o_bitv) = self.other;
+ // Merging the two words is a bit of an awkward dance since
+ // one Bitv might be longer than the other
+ let word_idx = self.next_idx / uint::BITS;
+ let w1 = if word_idx < s_bitv.storage.len() {
+ *s_bitv.storage.get(word_idx)
+ } else { 0 };
+ let w2 = if word_idx < o_bitv.storage.len() {
+ *o_bitv.storage.get(word_idx)
+ } else { 0 };
+ self.current_word = (self.merge)(w1, w2);
+ }
+
+ self.next_idx += 1;
+ if self.current_word & (1 << bit_idx) != 0 {
+ return Some(self.next_idx - 1);
+ }
+ }
+ return None;
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (uint, Option<uint>) {
+ let cap = cmp::max(self.set.capacity(), self.other.capacity());
+ (0, Some(cap - self.next_idx))
+ }
+}
+
#[cfg(test)]
mod tests {
use std::prelude::*;
use test::Bencher;
use {Set, Mutable, MutableSet};
- use bitv::{Bitv, SmallBitv, BigBitv, BitvSet, from_bools, from_fn,
- from_bytes};
+ use bitv::{Bitv, BitvSet, from_fn, from_bytes};
use bitv;
use vec::Vec;
#[test]
fn test_to_str() {
- let zerolen = Bitv::new(0u, false);
- assert_eq!(zerolen.to_str().as_slice(), "");
+ let zerolen = Bitv::new();
+ assert_eq!(zerolen.to_string().as_slice(), "");
- let eightbits = Bitv::new(8u, false);
- assert_eq!(eightbits.to_str().as_slice(), "00000000")
+ let eightbits = Bitv::with_capacity(8u, false);
+ assert_eq!(eightbits.to_string().as_slice(), "00000000")
}
#[test]
fn test_0_elements() {
- let act = Bitv::new(0u, false);
+ let act = Bitv::new();
let exp = Vec::from_elem(0u, false);
assert!(act.eq_vec(exp.as_slice()));
}
#[test]
fn test_1_element() {
- let mut act = Bitv::new(1u, false);
+ let mut act = Bitv::with_capacity(1u, false);
assert!(act.eq_vec([false]));
- act = Bitv::new(1u, true);
+ act = Bitv::with_capacity(1u, true);
assert!(act.eq_vec([true]));
}
#[test]
fn test_2_elements() {
- let mut b = bitv::Bitv::new(2, false);
+ let mut b = bitv::Bitv::with_capacity(2, false);
b.set(0, true);
b.set(1, false);
- assert_eq!(b.to_str().as_slice(), "10");
+ assert_eq!(b.to_string().as_slice(), "10");
}
#[test]
let mut act;
// all 0
- act = Bitv::new(10u, false);
+ act = Bitv::with_capacity(10u, false);
assert!((act.eq_vec(
[false, false, false, false, false, false, false, false, false, false])));
// all 1
- act = Bitv::new(10u, true);
+ act = Bitv::with_capacity(10u, true);
assert!((act.eq_vec([true, true, true, true, true, true, true, true, true, true])));
// mixed
- act = Bitv::new(10u, false);
+ act = Bitv::with_capacity(10u, false);
act.set(0u, true);
act.set(1u, true);
act.set(2u, true);
assert!((act.eq_vec([true, true, true, true, true, false, false, false, false, false])));
// mixed
- act = Bitv::new(10u, false);
+ act = Bitv::with_capacity(10u, false);
act.set(5u, true);
act.set(6u, true);
act.set(7u, true);
assert!((act.eq_vec([false, false, false, false, false, true, true, true, true, true])));
// mixed
- act = Bitv::new(10u, false);
+ act = Bitv::with_capacity(10u, false);
act.set(0u, true);
act.set(3u, true);
act.set(6u, true);
let mut act;
// all 0
- act = Bitv::new(31u, false);
+ act = Bitv::with_capacity(31u, false);
assert!(act.eq_vec(
[false, false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false]));
// all 1
- act = Bitv::new(31u, true);
+ act = Bitv::with_capacity(31u, true);
assert!(act.eq_vec(
[true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true]));
// mixed
- act = Bitv::new(31u, false);
+ act = Bitv::with_capacity(31u, false);
act.set(0u, true);
act.set(1u, true);
act.set(2u, true);
false, false, false, false, false, false]));
// mixed
- act = Bitv::new(31u, false);
+ act = Bitv::with_capacity(31u, false);
act.set(16u, true);
act.set(17u, true);
act.set(18u, true);
false, false, false, false, false, false, false]));
// mixed
- act = Bitv::new(31u, false);
+ act = Bitv::with_capacity(31u, false);
act.set(24u, true);
act.set(25u, true);
act.set(26u, true);
false, true, true, true, true, true, true, true]));
// mixed
- act = Bitv::new(31u, false);
+ act = Bitv::with_capacity(31u, false);
act.set(3u, true);
act.set(17u, true);
act.set(30u, true);
let mut act;
// all 0
- act = Bitv::new(32u, false);
+ act = Bitv::with_capacity(32u, false);
assert!(act.eq_vec(
[false, false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false]));
// all 1
- act = Bitv::new(32u, true);
+ act = Bitv::with_capacity(32u, true);
assert!(act.eq_vec(
[true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true]));
// mixed
- act = Bitv::new(32u, false);
+ act = Bitv::with_capacity(32u, false);
act.set(0u, true);
act.set(1u, true);
act.set(2u, true);
false, false, false, false, false, false, false]));
// mixed
- act = Bitv::new(32u, false);
+ act = Bitv::with_capacity(32u, false);
act.set(16u, true);
act.set(17u, true);
act.set(18u, true);
false, false, false, false, false, false, false, false]));
// mixed
- act = Bitv::new(32u, false);
+ act = Bitv::with_capacity(32u, false);
act.set(24u, true);
act.set(25u, true);
act.set(26u, true);
false, true, true, true, true, true, true, true, true]));
// mixed
- act = Bitv::new(32u, false);
+ act = Bitv::with_capacity(32u, false);
act.set(3u, true);
act.set(17u, true);
act.set(30u, true);
let mut act;
// all 0
- act = Bitv::new(33u, false);
+ act = Bitv::with_capacity(33u, false);
assert!(act.eq_vec(
[false, false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false]));
// all 1
- act = Bitv::new(33u, true);
+ act = Bitv::with_capacity(33u, true);
assert!(act.eq_vec(
[true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true]));
// mixed
- act = Bitv::new(33u, false);
+ act = Bitv::with_capacity(33u, false);
act.set(0u, true);
act.set(1u, true);
act.set(2u, true);
false, false, false, false, false, false, false, false]));
// mixed
- act = Bitv::new(33u, false);
+ act = Bitv::with_capacity(33u, false);
act.set(16u, true);
act.set(17u, true);
act.set(18u, true);
false, false, false, false, false, false, false, false, false]));
// mixed
- act = Bitv::new(33u, false);
+ act = Bitv::with_capacity(33u, false);
act.set(24u, true);
act.set(25u, true);
act.set(26u, true);
false, true, true, true, true, true, true, true, true, false]));
// mixed
- act = Bitv::new(33u, false);
+ act = Bitv::with_capacity(33u, false);
act.set(3u, true);
act.set(17u, true);
act.set(30u, true);
#[test]
fn test_equal_differing_sizes() {
- let v0 = Bitv::new(10u, false);
- let v1 = Bitv::new(11u, false);
+ let v0 = Bitv::with_capacity(10u, false);
+ let v1 = Bitv::with_capacity(11u, false);
assert!(v0 != v1);
}
#[test]
fn test_equal_greatly_differing_sizes() {
- let v0 = Bitv::new(10u, false);
- let v1 = Bitv::new(110u, false);
+ let v0 = Bitv::with_capacity(10u, false);
+ let v1 = Bitv::with_capacity(110u, false);
assert!(v0 != v1);
}
#[test]
fn test_equal_sneaky_small() {
- let mut a = bitv::Bitv::new(1, false);
+ let mut a = bitv::Bitv::with_capacity(1, false);
a.set(0, true);
- let mut b = bitv::Bitv::new(1, true);
+ let mut b = bitv::Bitv::with_capacity(1, true);
b.set(0, true);
assert_eq!(a, b);
#[test]
fn test_equal_sneaky_big() {
- let mut a = bitv::Bitv::new(100, false);
+ let mut a = bitv::Bitv::with_capacity(100, false);
for i in range(0u, 100) {
a.set(i, true);
}
- let mut b = bitv::Bitv::new(100, true);
+ let mut b = bitv::Bitv::with_capacity(100, true);
for i in range(0u, 100) {
b.set(i, true);
}
fn test_from_bytes() {
let bitv = from_bytes([0b10110110, 0b00000000, 0b11111111]);
let str = format!("{}{}{}", "10110110", "00000000", "11111111");
- assert_eq!(bitv.to_str().as_slice(), str.as_slice());
+ assert_eq!(bitv.to_string().as_slice(), str.as_slice());
}
#[test]
fn test_to_bytes() {
- let mut bv = Bitv::new(3, true);
+ let mut bv = Bitv::with_capacity(3, true);
bv.set(1, false);
assert_eq!(bv.to_bytes(), vec!(0b10100000));
- let mut bv = Bitv::new(9, false);
+ let mut bv = Bitv::with_capacity(9, false);
bv.set(2, true);
bv.set(8, true);
assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000));
#[test]
fn test_from_bools() {
- assert!(from_bools([true, false, true, true]).to_str().as_slice() ==
- "1011");
+ let bools = vec![true, false, true, true];
+ let bitv: Bitv = bools.iter().map(|n| *n).collect();
+ assert_eq!(bitv.to_string().as_slice(), "1011");
}
#[test]
fn test_to_bools() {
let bools = vec!(false, false, true, false, false, true, true, false);
- assert_eq!(from_bytes([0b00100110]).to_bools(), bools);
+ assert_eq!(from_bytes([0b00100110]).iter().collect::<Vec<bool>>(), bools);
}
#[test]
fn test_bitv_iterator() {
let bools = [true, false, true, true];
- let bitv = from_bools(bools);
+ let bitv: Bitv = bools.iter().map(|n| *n).collect();
for (act, &ex) in bitv.iter().zip(bools.iter()) {
assert_eq!(ex, act);
#[test]
fn test_bitv_set_iterator() {
let bools = [true, false, true, true];
- let bitv = BitvSet::from_bitv(from_bools(bools));
+ let bitv = BitvSet::from_bitv(bools.iter().map(|n| *n).collect());
let idxs: Vec<uint> = bitv.iter().collect();
assert_eq!(idxs, vec!(0, 2, 3));
let lengths = [10, 64, 100];
for &b in bools.iter() {
for &l in lengths.iter() {
- let bitset = BitvSet::from_bitv(Bitv::new(l, b));
+ let bitset = BitvSet::from_bitv(Bitv::with_capacity(l, b));
assert_eq!(bitset.contains(&1u), b)
assert_eq!(bitset.contains(&(l-1u)), b)
assert!(!bitset.contains(&l))
#[test]
fn test_small_difference() {
- let mut b1 = Bitv::new(3, false);
- let mut b2 = Bitv::new(3, false);
+ let mut b1 = Bitv::with_capacity(3, false);
+ let mut b2 = Bitv::with_capacity(3, false);
b1.set(0, true);
b1.set(1, true);
b2.set(1, true);
b2.set(2, true);
assert!(b1.difference(&b2));
- assert!(b1[0]);
- assert!(!b1[1]);
- assert!(!b1[2]);
+ assert!(b1.get(0));
+ assert!(!b1.get(1));
+ assert!(!b1.get(2));
}
#[test]
fn test_big_difference() {
- let mut b1 = Bitv::new(100, false);
- let mut b2 = Bitv::new(100, false);
+ let mut b1 = Bitv::with_capacity(100, false);
+ let mut b2 = Bitv::with_capacity(100, false);
b1.set(0, true);
b1.set(40, true);
b2.set(40, true);
b2.set(80, true);
assert!(b1.difference(&b2));
- assert!(b1[0]);
- assert!(!b1[40]);
- assert!(!b1[80]);
+ assert!(b1.get(0));
+ assert!(!b1.get(40));
+ assert!(!b1.get(80));
}
#[test]
fn test_small_clear() {
- let mut b = Bitv::new(14, true);
+ let mut b = Bitv::with_capacity(14, true);
b.clear();
- b.ones(|i| {
- fail!("found 1 at {:?}", i)
- });
+ assert!(b.none());
}
#[test]
fn test_big_clear() {
- let mut b = Bitv::new(140, true);
+ let mut b = Bitv::with_capacity(140, true);
b.clear();
- b.ones(|i| {
- fail!("found 1 at {:?}", i)
- });
+ assert!(b.none());
+ }
+
+ #[test]
+ fn test_bitv_masking() {
+ let b = Bitv::with_capacity(140, true);
+ let mut bs = BitvSet::from_bitv(b);
+ assert!(bs.contains(&139));
+ assert!(!bs.contains(&140));
+ assert!(bs.insert(150));
+ assert!(!bs.contains(&140));
+ assert!(!bs.contains(&149));
+ assert!(bs.contains(&150));
+ assert!(!bs.contains(&151));
}
#[test]
fn test_bitv_set_basic() {
+ // calculate nbits with uint::BITS granularity
+ fn calc_nbits(bits: uint) -> uint {
+ uint::BITS * ((bits + uint::BITS - 1) / uint::BITS)
+ }
+
let mut b = BitvSet::new();
+ assert_eq!(b.capacity(), calc_nbits(0));
assert!(b.insert(3));
+ assert_eq!(b.capacity(), calc_nbits(3));
assert!(!b.insert(3));
assert!(b.contains(&3));
+ assert!(b.insert(4));
+ assert!(!b.insert(4));
+ assert!(b.contains(&3));
assert!(b.insert(400));
+ assert_eq!(b.capacity(), calc_nbits(400));
assert!(!b.insert(400));
assert!(b.contains(&400));
- assert_eq!(b.len(), 2);
+ assert_eq!(b.len(), 3);
}
#[test]
assert!(b.insert(5));
assert!(b.insert(3));
- let mut i = 0;
let expected = [3, 5, 11, 77];
- a.intersection(&b, |x| {
- assert_eq!(*x, expected[i]);
- i += 1;
- true
- });
- assert_eq!(i, expected.len());
+ let actual = a.intersection(&b).collect::<Vec<uint>>();
+ assert_eq!(actual.as_slice(), expected.as_slice());
}
#[test]
assert!(b.insert(3));
assert!(b.insert(200));
- let mut i = 0;
let expected = [1, 5, 500];
- a.difference(&b, |x| {
- assert_eq!(*x, expected[i]);
- i += 1;
- true
- });
- assert_eq!(i, expected.len());
+ let actual = a.difference(&b).collect::<Vec<uint>>();
+ assert_eq!(actual.as_slice(), expected.as_slice());
}
#[test]
assert!(b.insert(14));
assert!(b.insert(220));
- let mut i = 0;
let expected = [1, 5, 11, 14, 220];
- a.symmetric_difference(&b, |x| {
- assert_eq!(*x, expected[i]);
- i += 1;
- true
- });
- assert_eq!(i, expected.len());
+ let actual = a.symmetric_difference(&b).collect::<Vec<uint>>();
+ assert_eq!(actual.as_slice(), expected.as_slice());
}
#[test]
assert!(b.insert(13));
assert!(b.insert(19));
- let mut i = 0;
let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160];
- a.union(&b, |x| {
- assert_eq!(*x, expected[i]);
- i += 1;
- true
- });
- assert_eq!(i, expected.len());
+ let actual = a.union(&b).collect::<Vec<uint>>();
+ assert_eq!(actual.as_slice(), expected.as_slice());
+ }
+
+ #[test]
+ fn test_bitv_set_subset() {
+ let mut set1 = BitvSet::new();
+ let mut set2 = BitvSet::new();
+
+ assert!(set1.is_subset(&set2)); // {} {}
+ set2.insert(100);
+ assert!(set1.is_subset(&set2)); // {} { 1 }
+ set2.insert(200);
+ assert!(set1.is_subset(&set2)); // {} { 1, 2 }
+ set1.insert(200);
+ assert!(set1.is_subset(&set2)); // { 2 } { 1, 2 }
+ set1.insert(300);
+ assert!(!set1.is_subset(&set2)); // { 2, 3 } { 1, 2 }
+ set2.insert(300);
+ assert!(set1.is_subset(&set2)); // { 2, 3 } { 1, 2, 3 }
+ set2.insert(400);
+ assert!(set1.is_subset(&set2)); // { 2, 3 } { 1, 2, 3, 4 }
+ set2.remove(&100);
+ assert!(set1.is_subset(&set2)); // { 2, 3 } { 2, 3, 4 }
+ set2.remove(&300);
+ assert!(!set1.is_subset(&set2)); // { 2, 3 } { 2, 4 }
+ set1.remove(&300);
+ assert!(set1.is_subset(&set2)); // { 2 } { 2, 4 }
}
#[test]
assert!(a.insert(1000));
assert!(a.remove(&1000));
+ a.shrink_to_fit();
assert_eq!(a.capacity(), uint::BITS);
}
assert!(!v.none());
}
+ #[test]
+ fn test_bitv_push_pop() {
+ let mut s = Bitv::with_capacity(5 * uint::BITS - 2, false);
+ assert_eq!(s.len(), 5 * uint::BITS - 2);
+ assert_eq!(s.get(5 * uint::BITS - 3), false);
+ s.push(true);
+ s.push(true);
+ assert_eq!(s.get(5 * uint::BITS - 2), true);
+ assert_eq!(s.get(5 * uint::BITS - 1), true);
+ // Here the internal vector will need to be extended
+ s.push(false);
+ assert_eq!(s.get(5 * uint::BITS), false);
+ s.push(false);
+ assert_eq!(s.get(5 * uint::BITS + 1), false);
+ assert_eq!(s.len(), 5 * uint::BITS + 2);
+ // Pop it all off
+ assert_eq!(s.pop(), false);
+ assert_eq!(s.pop(), false);
+ assert_eq!(s.pop(), true);
+ assert_eq!(s.pop(), true);
+ assert_eq!(s.len(), 5 * uint::BITS - 2);
+ }
+
+ #[test]
+ fn test_bitv_truncate() {
+ let mut s = Bitv::with_capacity(5 * uint::BITS, true);
+
+ assert_eq!(s, Bitv::with_capacity(5 * uint::BITS, true));
+ assert_eq!(s.len(), 5 * uint::BITS);
+ s.truncate(4 * uint::BITS);
+ assert_eq!(s, Bitv::with_capacity(4 * uint::BITS, true));
+ assert_eq!(s.len(), 4 * uint::BITS);
+ // Truncating to a size > s.len() should be a noop
+ s.truncate(5 * uint::BITS);
+ assert_eq!(s, Bitv::with_capacity(4 * uint::BITS, true));
+ assert_eq!(s.len(), 4 * uint::BITS);
+ s.truncate(3 * uint::BITS - 10);
+ assert_eq!(s, Bitv::with_capacity(3 * uint::BITS - 10, true));
+ assert_eq!(s.len(), 3 * uint::BITS - 10);
+ s.truncate(0);
+ assert_eq!(s, Bitv::with_capacity(0, true));
+ assert_eq!(s.len(), 0);
+ }
+
+ #[test]
+ fn test_bitv_reserve() {
+ let mut s = Bitv::with_capacity(5 * uint::BITS, true);
+ // Check capacity
+ assert_eq!(s.capacity(), 5 * uint::BITS);
+ s.reserve(2 * uint::BITS);
+ assert_eq!(s.capacity(), 5 * uint::BITS);
+ s.reserve(7 * uint::BITS);
+ assert_eq!(s.capacity(), 7 * uint::BITS);
+ s.reserve(7 * uint::BITS);
+ assert_eq!(s.capacity(), 7 * uint::BITS);
+ s.reserve(7 * uint::BITS + 1);
+ assert_eq!(s.capacity(), 8 * uint::BITS);
+ // Check that length hasn't changed
+ assert_eq!(s.len(), 5 * uint::BITS);
+ s.push(true);
+ s.push(false);
+ s.push(true);
+ assert_eq!(s.get(5 * uint::BITS - 1), true);
+ assert_eq!(s.get(5 * uint::BITS - 0), true);
+ assert_eq!(s.get(5 * uint::BITS + 1), false);
+ assert_eq!(s.get(5 * uint::BITS + 2), true);
+ }
+
+ #[test]
+ fn test_bitv_grow() {
+ let mut bitv = from_bytes([0b10110110, 0b00000000, 0b10101010]);
+ bitv.grow(32, true);
+ assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b10101010,
+ 0xFF, 0xFF, 0xFF, 0xFF]));
+ bitv.grow(64, false);
+ assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b10101010,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0]));
+ bitv.grow(16, true);
+ assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b10101010,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]));
+ }
+
+ #[test]
+ fn test_bitv_extend() {
+ let mut bitv = from_bytes([0b10110110, 0b00000000, 0b11111111]);
+ let ext = from_bytes([0b01001001, 0b10010010, 0b10111101]);
+ bitv.extend(ext.iter());
+ assert_eq!(bitv, from_bytes([0b10110110, 0b00000000, 0b11111111,
+ 0b01001001, 0b10010010, 0b10111101]));
+ }
+
#[test]
fn test_bitv_set_show() {
let mut s = BitvSet::new();
s.insert(10);
s.insert(50);
s.insert(2);
- assert_eq!("{1, 2, 10, 50}".to_string(), s.to_str());
+ assert_eq!("{1, 2, 10, 50}".to_string(), s.to_string());
}
fn rng() -> rand::IsaacRng {
})
}
- #[bench]
- fn bench_small_bitv_small(b: &mut Bencher) {
- let mut r = rng();
- let mut bitv = SmallBitv::new(uint::BITS);
- b.iter(|| {
- bitv.set((r.next_u32() as uint) % uint::BITS, true);
- &bitv
- })
- }
-
- #[bench]
- fn bench_big_bitv_small(b: &mut Bencher) {
- let mut r = rng();
- let mut bitv = BigBitv::new(vec!(0));
- b.iter(|| {
- bitv.set((r.next_u32() as uint) % uint::BITS, true);
- &bitv
- })
- }
-
- #[bench]
- fn bench_big_bitv_big(b: &mut Bencher) {
- let mut r = rng();
- let mut storage = vec!();
- storage.grow(BENCH_BITS / uint::BITS, &0u);
- let mut bitv = BigBitv::new(storage);
- b.iter(|| {
- bitv.set((r.next_u32() as uint) % BENCH_BITS, true);
- &bitv
- })
- }
-
#[bench]
fn bench_bitv_big(b: &mut Bencher) {
let mut r = rng();
- let mut bitv = Bitv::new(BENCH_BITS, false);
+ let mut bitv = Bitv::with_capacity(BENCH_BITS, false);
b.iter(|| {
bitv.set((r.next_u32() as uint) % BENCH_BITS, true);
&bitv
#[bench]
fn bench_bitv_small(b: &mut Bencher) {
let mut r = rng();
- let mut bitv = Bitv::new(uint::BITS, false);
+ let mut bitv = Bitv::with_capacity(uint::BITS, false);
b.iter(|| {
bitv.set((r.next_u32() as uint) % uint::BITS, true);
&bitv
#[bench]
fn bench_bitv_big_union(b: &mut Bencher) {
- let mut b1 = Bitv::new(BENCH_BITS, false);
- let b2 = Bitv::new(BENCH_BITS, false);
+ let mut b1 = Bitv::with_capacity(BENCH_BITS, false);
+ let b2 = Bitv::with_capacity(BENCH_BITS, false);
b.iter(|| {
b1.union(&b2);
})
#[bench]
fn bench_btv_small_iter(b: &mut Bencher) {
- let bitv = Bitv::new(uint::BITS, false);
+ let bitv = Bitv::with_capacity(uint::BITS, false);
b.iter(|| {
let mut _sum = 0;
for pres in bitv.iter() {
#[bench]
fn bench_bitv_big_iter(b: &mut Bencher) {
- let bitv = Bitv::new(BENCH_BITS, false);
+ let bitv = Bitv::with_capacity(BENCH_BITS, false);
b.iter(|| {
let mut _sum = 0;
for pres in bitv.iter() {
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use core::fmt;
use core::fmt::Show;
fn insert_test_one() {
let b = BTree::new(1i, "abc".to_string(), 2);
let is_insert = b.insert(2i, "xyz".to_string());
- //println!("{}", is_insert.clone().to_str());
assert!(is_insert.root.is_leaf());
}
let leaf_elt_3 = LeafElt::new(3i, "ccc".to_string());
let n = Node::new_leaf(vec!(leaf_elt_1, leaf_elt_2, leaf_elt_3));
let b = BTree::new_with_node_len(n, 3, 2);
- //println!("{}", b.clone().insert(4, "ddd".to_string()).to_str());
+ //println!("{}", b.clone().insert(4, "ddd".to_string()).to_string());
assert!(b.insert(4, "ddd".to_string()).root.is_leaf());
}
let leaf_elt_4 = LeafElt::new(4i, "ddd".to_string());
let n = Node::new_leaf(vec!(leaf_elt_1, leaf_elt_2, leaf_elt_3, leaf_elt_4));
let b = BTree::new_with_node_len(n, 3, 2);
- //println!("{}", b.clone().insert(5, "eee".to_string()).to_str());
+ //println!("{}", b.clone().insert(5, "eee".to_string()).to_string());
assert!(!b.insert(5, "eee".to_string()).root.is_leaf());
}
b = b.clone().insert(7, "ggg".to_string());
b = b.clone().insert(8, "hhh".to_string());
b = b.clone().insert(0, "omg".to_string());
- //println!("{}", b.clone().to_str());
+ //println!("{}", b.clone().to_string());
assert!(!b.root.is_leaf());
}
assert!(&b2.cmp(&b) == &Greater)
}
- //Tests the BTree's to_str() method.
+ //Tests the BTree's to_string() method.
#[test]
fn btree_tostr_test() {
let b = BTree::new(1i, "abc".to_string(), 2);
- assert_eq!(b.to_str(), "Key: 1, value: abc;".to_string())
+ assert_eq!(b.to_string(), "Key: 1, value: abc;".to_string())
}
}
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use core::default::Default;
use core::fmt;
use core::iter;
#[test]
fn test_show() {
let list: DList<int> = range(0i, 10).collect();
- assert!(list.to_str().as_slice() == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
+ assert!(list.to_string().as_slice() == "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
let list: DList<&str> = vec!["just", "one", "test", "more"].iter()
.map(|&s| s)
.collect();
- assert!(list.to_str().as_slice() == "[just, one, test, more]");
+ assert!(list.to_string().as_slice() == "[just, one, test, more]");
}
#[cfg(test)]
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use alloc::rc::Rc;
use core::intrinsics::TypeId;
use core::mem;
mod tests {
use test::Bencher;
use std::prelude::*;
- use std::num::ToStrRadix;
+ use std::fmt;
use str::Str;
use string::String;
fn to_hex_str(r: &[u8, ..8]) -> String {
let mut s = String::new();
for b in r.iter() {
- s.push_str((*b as uint).to_str_radix(16u).as_slice());
+ s.push_str(format!("{}", fmt::radix(*b, 16)).as_slice());
}
s
}
let r = result_bytes(h);
let mut s = String::new();
for b in r.iter() {
- s.push_str((*b as uint).to_str_radix(16u).as_slice());
+ s.push_str(format!("{}", fmt::radix(*b, 16)).as_slice());
}
s
}
* Collection types.
*/
-#![crate_id = "collections#0.11.0"]
+#![crate_name = "collections"]
#![experimental]
#![crate_type = "rlib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
#![feature(macro_rules, managed_boxes, default_type_params, phase, globs)]
#![no_std]
#[phase(plugin, link)] extern crate core;
+extern crate unicode;
extern crate alloc;
#[cfg(test)] extern crate native;
pub mod vec;
pub mod hash;
-// Internal unicode fiddly bits for the str module
-mod unicode;
-
mod deque;
/// A trait to represent mutable containers
map.insert(1, 2i);
map.insert(3, 4i);
- let map_str = map.to_str();
+ let map_str = map.to_string();
let map_str = map_str.as_slice();
assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
assert_eq!(format!("{}", empty), "{}".to_string());
use core::prelude::*;
-use core::char;
use core::default::Default;
use core::fmt;
use core::cmp;
use Collection;
use hash;
use string::String;
+use unicode;
use vec::Vec;
pub use core::str::{from_utf8, CharEq, Chars, CharOffsets};
pub use core::str::{Bytes, CharSplits};
-pub use core::str::{CharSplitsN, Words, AnyLines, MatchIndices, StrSplits};
+pub use core::str::{CharSplitsN, AnyLines, MatchIndices, StrSplits};
pub use core::str::{eq_slice, is_utf8, is_utf16, Utf16Items};
pub use core::str::{Utf16Item, ScalarValue, LoneSurrogate, utf16_items};
pub use core::str::{truncate_utf16_at_nul, utf8_char_width, CharRange};
pub use core::str::{Str, StrSlice};
+pub use unicode::{Words, UnicodeStrSlice};
/*
Section: Creating a string
impl<'a> Iterator<char> for Decompositions<'a> {
#[inline]
fn next(&mut self) -> Option<char> {
- use unicode::normalization::canonical_combining_class;
+ use unicode::canonical_combining_class;
match self.buffer.as_slice().head() {
Some(&(c, 0)) => {
}
let decomposer = match self.kind {
- Canonical => char::decompose_canonical,
- Compatible => char::decompose_compatible
+ Canonical => unicode::char::decompose_canonical,
+ Compatible => unicode::char::decompose_compatible
};
if !self.sorted {
/// # Return value
///
/// The original string with all occurrences of `from` replaced with `to`
+///
+/// # Example
+///
+/// ```rust
+/// use std::str;
+/// let string = "orange";
+/// let new_string = str::replace(string, "or", "str");
+/// assert_eq!(new_string.as_slice(), "strange");
+/// ```
pub fn replace(s: &str, from: &str, to: &str) -> String {
let mut result = String::new();
let mut last_end = 0;
impl<'a> MaybeOwned<'a> {
/// Returns `true` if this `MaybeOwned` wraps an owned string
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// let string = String::from_str("orange");
+ /// let maybe_owned_string = string.into_maybe_owned();
+ /// assert_eq!(true, maybe_owned_string.is_owned());
+ /// ```
#[inline]
pub fn is_owned(&self) -> bool {
match *self {
}
/// Returns `true` if this `MaybeOwned` wraps a borrowed string
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// let string = "orange";
+ /// let maybe_owned_string = string.as_slice().into_maybe_owned();
+ /// assert_eq!(true, maybe_owned_string.is_slice());
+ /// ```
#[inline]
pub fn is_slice(&self) -> bool {
match *self {
fn into_maybe_owned(self) -> MaybeOwned<'a>;
}
+/// # Example
+///
+/// ```rust
+/// let owned_string = String::from_str("orange");
+/// let maybe_owned_string = owned_string.into_maybe_owned();
+/// assert_eq!(true, maybe_owned_string.is_owned());
+/// ```
impl<'a> IntoMaybeOwned<'a> for String {
#[inline]
fn into_maybe_owned(self) -> MaybeOwned<'a> {
}
}
+/// # Example
+///
+/// ```rust
+/// let string = "orange";
+/// let maybe_owned_str = string.as_slice().into_maybe_owned();
+/// assert_eq!(false, maybe_owned_str.is_owned());
+/// ```
impl<'a> IntoMaybeOwned<'a> for &'a str {
#[inline]
fn into_maybe_owned(self) -> MaybeOwned<'a> { Slice(self) }
}
+/// # Example
+///
+/// ```rust
+/// let str = "orange";
+/// let maybe_owned_str = str.as_slice().into_maybe_owned();
+/// let maybe_maybe_owned_str = maybe_owned_str.into_maybe_owned();
+/// assert_eq!(false, maybe_maybe_owned_str.is_owned());
+/// ```
impl<'a> IntoMaybeOwned<'a> for MaybeOwned<'a> {
#[inline]
fn into_maybe_owned(self) -> MaybeOwned<'a> { self }
#[inline]
fn into_string(self) -> String {
match self {
- Slice(s) => s.to_string(),
+ Slice(s) => String::from_str(s),
Owned(s) => s
}
}
fn clone(&self) -> MaybeOwned<'a> {
match *self {
Slice(s) => Slice(s),
- Owned(ref s) => Owned(s.to_string())
+ Owned(ref s) => Owned(String::from_str(s.as_slice()))
}
}
}
let a = vec![65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 0u8];
let b = a.as_ptr();
let c = from_buf_len(b, 3u);
- assert_eq!(c, "AAA".to_string());
+ assert_eq!(c, String::from_str("AAA"));
}
}
}
/// Convert `self` into a `String`, not making a copy if possible.
fn into_string(self) -> String;
- /// Convert `self` into a `String`.
- #[inline]
- fn to_string(&self) -> String {
- String::from_str(self.as_slice())
- }
-
#[allow(missing_doc)]
#[deprecated = "replaced by .into_string()"]
fn into_owned(self) -> String {
impl<'a> StrAllocating for &'a str {
#[inline]
fn into_string(self) -> String {
- self.to_string()
+ String::from_str(self)
}
}
#[cfg(test)]
mod tests {
- use std::prelude::*;
use std::iter::AdditiveIterator;
use std::default::Default;
+ use std::char::Char;
+ use std::clone::Clone;
+ use std::cmp::{Equal, Greater, Less, Ord, Eq, PartialOrd, PartialEq, Equiv};
+ use std::result::{Ok, Err};
+ use std::option::{Some, None};
+ use std::ptr::RawPtr;
+ use std::iter::{Iterator, DoubleEndedIterator};
+ use Collection;
- use str::*;
+ use super::*;
+ use std::slice::{Vector, ImmutableVector};
use string::String;
use vec::Vec;
+ use unicode::UnicodeChar;
+
#[test]
fn test_eq_slice() {
assert!((eq_slice("foobar".slice(0, 3), "foo")));
#[test]
fn test_collect() {
- let empty = "".to_string();
+ let empty = String::from_str("");
let s: String = empty.as_slice().chars().collect();
assert_eq!(empty, s);
- let data = "ประเทศไทย中".to_string();
+ let data = String::from_str("ประเทศไทย中");
let s: String = data.as_slice().chars().collect();
assert_eq!(data, s);
}
#[test]
fn test_into_bytes() {
- let data = "asdf".to_string();
+ let data = String::from_str("asdf");
let buf = data.into_bytes();
assert_eq!(b"asdf", buf.as_slice());
}
assert!(data.slice(2u, 4u).find_str("ab").is_none());
let string = "ประเทศไทย中华Việt Nam";
- let mut data = string.to_string();
+ let mut data = String::from_str(string);
data.push_str(string);
assert!(data.as_slice().find_str("ไท华").is_none());
assert_eq!(data.as_slice().slice(0u, 43u).find_str(""), Some(0u));
fn t(v: &[String], s: &str) {
assert_eq!(v.concat().as_slice(), s);
}
- t(["you".to_string(), "know".to_string(), "I'm".to_string(),
- "no".to_string(), "good".to_string()], "youknowI'mnogood");
+ t([String::from_str("you"), String::from_str("know"),
+ String::from_str("I'm"),
+ String::from_str("no"), String::from_str("good")],
+ "youknowI'mnogood");
let v: &[String] = [];
t(v, "");
- t(["hi".to_string()], "hi");
+ t([String::from_str("hi")], "hi");
}
#[test]
fn t(v: &[String], sep: &str, s: &str) {
assert_eq!(v.connect(sep).as_slice(), s);
}
- t(["you".to_string(), "know".to_string(), "I'm".to_string(),
- "no".to_string(), "good".to_string()],
+ t([String::from_str("you"), String::from_str("know"),
+ String::from_str("I'm"),
+ String::from_str("no"), String::from_str("good")],
" ", "you know I'm no good");
let v: &[String] = [];
t(v, " ", "");
- t(["hi".to_string()], " ", "hi");
+ t([String::from_str("hi")], " ", "hi");
}
#[test]
#[test]
fn test_repeat() {
- assert_eq!("x".repeat(4), "xxxx".to_string());
- assert_eq!("hi".repeat(4), "hihihihi".to_string());
- assert_eq!("ไท华".repeat(3), "ไท华ไท华ไท华".to_string());
- assert_eq!("".repeat(4), "".to_string());
- assert_eq!("hi".repeat(0), "".to_string());
+ assert_eq!("x".repeat(4), String::from_str("xxxx"));
+ assert_eq!("hi".repeat(4), String::from_str("hihihihi"));
+ assert_eq!("ไท华".repeat(3), String::from_str("ไท华ไท华ไท华"));
+ assert_eq!("".repeat(4), String::from_str(""));
+ assert_eq!("hi".repeat(0), String::from_str(""));
}
#[test]
}
let letters = a_million_letter_a();
assert!(half_a_million_letter_a() ==
- unsafe {raw::slice_bytes(letters.as_slice(),
+ unsafe {String::from_str(raw::slice_bytes(letters.as_slice(),
0u,
- 500000)}.to_string());
+ 500000))});
}
#[test]
#[test]
fn test_replace() {
let a = "a";
- assert_eq!("".replace(a, "b"), "".to_string());
- assert_eq!("a".replace(a, "b"), "b".to_string());
- assert_eq!("ab".replace(a, "b"), "bb".to_string());
+ assert_eq!("".replace(a, "b"), String::from_str(""));
+ assert_eq!("a".replace(a, "b"), String::from_str("b"));
+ assert_eq!("ab".replace(a, "b"), String::from_str("bb"));
let test = "test";
assert!(" test test ".replace(test, "toast") ==
- " toast toast ".to_string());
- assert_eq!(" test test ".replace(test, ""), " ".to_string());
+ String::from_str(" toast toast "));
+ assert_eq!(" test test ".replace(test, ""), String::from_str(" "));
}
#[test]
}
let letters = a_million_letter_x();
assert!(half_a_million_letter_x() ==
- letters.as_slice().slice(0u, 3u * 500000u).to_string());
+ String::from_str(letters.as_slice().slice(0u, 3u * 500000u)));
}
#[test]
let a = vec![65, 65, 65, 65, 65, 65, 65, 0];
let b = a.as_ptr();
let c = raw::from_c_str(b);
- assert_eq!(c, "AAAAAAA".to_string());
+ assert_eq!(c, String::from_str("AAAAAAA"));
}
}
fn test_as_bytes_fail() {
// Don't double free. (I'm not sure if this exercises the
// original problem code path anymore.)
- let s = "".to_string();
+ let s = String::from_str("");
let _bytes = s.as_bytes();
fail!();
}
#[test]
fn vec_str_conversions() {
- let s1: String = "All mimsy were the borogoves".to_string();
+ let s1: String = String::from_str("All mimsy were the borogoves");
let v: Vec<u8> = Vec::from_slice(s1.as_bytes());
- let s2: String = from_utf8(v.as_slice()).unwrap().to_string();
+ let s2: String = String::from_str(from_utf8(v.as_slice()).unwrap());
let mut i: uint = 0u;
let n1: uint = s1.len();
let n2: uint = v.len();
#[test]
fn test_utf16() {
let pairs =
- [("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n".to_string(),
+ [(String::from_str("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
vec![0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
0xd800_u16, 0xdf3b_u16, 0xd800_u16, 0xdf46_u16,
0xd800_u16, 0xdf39_u16, 0xd800_u16, 0xdf3b_u16,
0xd800_u16, 0xdf30_u16, 0x000a_u16]),
- ("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n".to_string(),
+ (String::from_str("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
vec![0xd801_u16, 0xdc12_u16, 0xd801_u16,
0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16,
0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16,
0xd801_u16, 0xdc32_u16, 0xd801_u16, 0xdc4d_u16,
0x000a_u16]),
- ("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n".to_string(),
+ (String::from_str("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
vec![0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
0xd800_u16, 0xdf0b_u16, 0xd800_u16, 0xdf04_u16,
0xd800_u16, 0xdf11_u16, 0xd800_u16, 0xdf09_u16,
0xdf04_u16, 0xd800_u16, 0xdf0b_u16, 0xd800_u16,
0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]),
- ("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n".to_string(),
+ (String::from_str("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
vec![0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
0xd801_u16, 0xdc88_u16, 0xd801_u16, 0xdc91_u16,
0xd801_u16, 0xdc9b_u16, 0xd801_u16, 0xdc92_u16,
0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16,
0x000a_u16 ]),
// Issue #12318, even-numbered non-BMP planes
- ("\U00020000".to_string(),
+ (String::from_str("\U00020000"),
vec![0xD840, 0xDC00])];
for p in pairs.iter() {
fn test_utf16_lossy() {
// completely positive cases tested above.
// lead + eof
- assert_eq!(from_utf16_lossy([0xD800]), "\uFFFD".to_string());
+ assert_eq!(from_utf16_lossy([0xD800]), String::from_str("\uFFFD"));
// lead + lead
- assert_eq!(from_utf16_lossy([0xD800, 0xD800]), "\uFFFD\uFFFD".to_string());
+ assert_eq!(from_utf16_lossy([0xD800, 0xD800]), String::from_str("\uFFFD\uFFFD"));
// isolated trail
- assert_eq!(from_utf16_lossy([0x0061, 0xDC00]), "a\uFFFD".to_string());
+ assert_eq!(from_utf16_lossy([0x0061, 0xDC00]), String::from_str("a\uFFFD"));
// general
assert_eq!(from_utf16_lossy([0xD800, 0xd801, 0xdc8b, 0xD800]),
- "\uFFFD𐒋\uFFFD".to_string());
+ String::from_str("\uFFFD𐒋\uFFFD"));
}
#[test]
#[test]
fn test_escape_unicode() {
- assert_eq!("abc".escape_unicode(), "\\x61\\x62\\x63".to_string());
- assert_eq!("a c".escape_unicode(), "\\x61\\x20\\x63".to_string());
- assert_eq!("\r\n\t".escape_unicode(), "\\x0d\\x0a\\x09".to_string());
- assert_eq!("'\"\\".escape_unicode(), "\\x27\\x22\\x5c".to_string());
- assert_eq!("\x00\x01\xfe\xff".escape_unicode(), "\\x00\\x01\\xfe\\xff".to_string());
- assert_eq!("\u0100\uffff".escape_unicode(), "\\u0100\\uffff".to_string());
- assert_eq!("\U00010000\U0010ffff".escape_unicode(), "\\U00010000\\U0010ffff".to_string());
- assert_eq!("ab\ufb00".escape_unicode(), "\\x61\\x62\\ufb00".to_string());
- assert_eq!("\U0001d4ea\r".escape_unicode(), "\\U0001d4ea\\x0d".to_string());
+ assert_eq!("abc".escape_unicode(), String::from_str("\\x61\\x62\\x63"));
+ assert_eq!("a c".escape_unicode(), String::from_str("\\x61\\x20\\x63"));
+ assert_eq!("\r\n\t".escape_unicode(), String::from_str("\\x0d\\x0a\\x09"));
+ assert_eq!("'\"\\".escape_unicode(), String::from_str("\\x27\\x22\\x5c"));
+ assert_eq!("\x00\x01\xfe\xff".escape_unicode(), String::from_str("\\x00\\x01\\xfe\\xff"));
+ assert_eq!("\u0100\uffff".escape_unicode(), String::from_str("\\u0100\\uffff"));
+ assert_eq!("\U00010000\U0010ffff".escape_unicode(),
+ String::from_str("\\U00010000\\U0010ffff"));
+ assert_eq!("ab\ufb00".escape_unicode(), String::from_str("\\x61\\x62\\ufb00"));
+ assert_eq!("\U0001d4ea\r".escape_unicode(), String::from_str("\\U0001d4ea\\x0d"));
}
#[test]
fn test_escape_default() {
- assert_eq!("abc".escape_default(), "abc".to_string());
- assert_eq!("a c".escape_default(), "a c".to_string());
- assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t".to_string());
- assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\".to_string());
- assert_eq!("\u0100\uffff".escape_default(), "\\u0100\\uffff".to_string());
- assert_eq!("\U00010000\U0010ffff".escape_default(), "\\U00010000\\U0010ffff".to_string());
- assert_eq!("ab\ufb00".escape_default(), "ab\\ufb00".to_string());
- assert_eq!("\U0001d4ea\r".escape_default(), "\\U0001d4ea\\r".to_string());
+ assert_eq!("abc".escape_default(), String::from_str("abc"));
+ assert_eq!("a c".escape_default(), String::from_str("a c"));
+ assert_eq!("\r\n\t".escape_default(), String::from_str("\\r\\n\\t"));
+ assert_eq!("'\"\\".escape_default(), String::from_str("\\'\\\"\\\\"));
+ assert_eq!("\u0100\uffff".escape_default(), String::from_str("\\u0100\\uffff"));
+ assert_eq!("\U00010000\U0010ffff".escape_default(),
+ String::from_str("\\U00010000\\U0010ffff"));
+ assert_eq!("ab\ufb00".escape_default(), String::from_str("ab\\ufb00"));
+ assert_eq!("\U0001d4ea\r".escape_default(), String::from_str("\\U0001d4ea\\r"));
}
#[test]
#[test]
fn test_nfd_chars() {
- assert_eq!("abc".nfd_chars().collect::<String>(), "abc".to_string());
- assert_eq!("\u1e0b\u01c4".nfd_chars().collect::<String>(), "d\u0307\u01c4".to_string());
- assert_eq!("\u2026".nfd_chars().collect::<String>(), "\u2026".to_string());
- assert_eq!("\u2126".nfd_chars().collect::<String>(), "\u03a9".to_string());
- assert_eq!("\u1e0b\u0323".nfd_chars().collect::<String>(), "d\u0323\u0307".to_string());
- assert_eq!("\u1e0d\u0307".nfd_chars().collect::<String>(), "d\u0323\u0307".to_string());
- assert_eq!("a\u0301".nfd_chars().collect::<String>(), "a\u0301".to_string());
- assert_eq!("\u0301a".nfd_chars().collect::<String>(), "\u0301a".to_string());
- assert_eq!("\ud4db".nfd_chars().collect::<String>(), "\u1111\u1171\u11b6".to_string());
- assert_eq!("\uac1c".nfd_chars().collect::<String>(), "\u1100\u1162".to_string());
+ assert_eq!("abc".nfd_chars().collect::<String>(), String::from_str("abc"));
+ assert_eq!("\u1e0b\u01c4".nfd_chars().collect::<String>(),
+ String::from_str("d\u0307\u01c4"));
+ assert_eq!("\u2026".nfd_chars().collect::<String>(), String::from_str("\u2026"));
+ assert_eq!("\u2126".nfd_chars().collect::<String>(), String::from_str("\u03a9"));
+ assert_eq!("\u1e0b\u0323".nfd_chars().collect::<String>(),
+ String::from_str("d\u0323\u0307"));
+ assert_eq!("\u1e0d\u0307".nfd_chars().collect::<String>(),
+ String::from_str("d\u0323\u0307"));
+ assert_eq!("a\u0301".nfd_chars().collect::<String>(), String::from_str("a\u0301"));
+ assert_eq!("\u0301a".nfd_chars().collect::<String>(), String::from_str("\u0301a"));
+ assert_eq!("\ud4db".nfd_chars().collect::<String>(),
+ String::from_str("\u1111\u1171\u11b6"));
+ assert_eq!("\uac1c".nfd_chars().collect::<String>(), String::from_str("\u1100\u1162"));
}
#[test]
fn test_nfkd_chars() {
- assert_eq!("abc".nfkd_chars().collect::<String>(), "abc".to_string());
- assert_eq!("\u1e0b\u01c4".nfkd_chars().collect::<String>(), "d\u0307DZ\u030c".to_string());
- assert_eq!("\u2026".nfkd_chars().collect::<String>(), "...".to_string());
- assert_eq!("\u2126".nfkd_chars().collect::<String>(), "\u03a9".to_string());
- assert_eq!("\u1e0b\u0323".nfkd_chars().collect::<String>(), "d\u0323\u0307".to_string());
- assert_eq!("\u1e0d\u0307".nfkd_chars().collect::<String>(), "d\u0323\u0307".to_string());
- assert_eq!("a\u0301".nfkd_chars().collect::<String>(), "a\u0301".to_string());
- assert_eq!("\u0301a".nfkd_chars().collect::<String>(), "\u0301a".to_string());
- assert_eq!("\ud4db".nfkd_chars().collect::<String>(), "\u1111\u1171\u11b6".to_string());
- assert_eq!("\uac1c".nfkd_chars().collect::<String>(), "\u1100\u1162".to_string());
+ assert_eq!("abc".nfkd_chars().collect::<String>(), String::from_str("abc"));
+ assert_eq!("\u1e0b\u01c4".nfkd_chars().collect::<String>(),
+ String::from_str("d\u0307DZ\u030c"));
+ assert_eq!("\u2026".nfkd_chars().collect::<String>(), String::from_str("..."));
+ assert_eq!("\u2126".nfkd_chars().collect::<String>(), String::from_str("\u03a9"));
+ assert_eq!("\u1e0b\u0323".nfkd_chars().collect::<String>(),
+ String::from_str("d\u0323\u0307"));
+ assert_eq!("\u1e0d\u0307".nfkd_chars().collect::<String>(),
+ String::from_str("d\u0323\u0307"));
+ assert_eq!("a\u0301".nfkd_chars().collect::<String>(), String::from_str("a\u0301"));
+ assert_eq!("\u0301a".nfkd_chars().collect::<String>(),
+ String::from_str("\u0301a"));
+ assert_eq!("\ud4db".nfkd_chars().collect::<String>(),
+String::from_str("\u1111\u1171\u11b6"));
+ assert_eq!("\uac1c".nfkd_chars().collect::<String>(), String::from_str("\u1100\u1162"));
}
#[test]
v.iter().map(|x| x.len()).sum()
}
- let s = "01234".to_string();
+ let s = String::from_str("01234");
assert_eq!(5, sum_len(["012", "", "34"]));
- assert_eq!(5, sum_len(["01".to_string(), "2".to_string(),
- "34".to_string(), "".to_string()]));
+ assert_eq!(5, sum_len([String::from_str("01"), String::from_str("2"),
+ String::from_str("34"), String::from_str("")]));
assert_eq!(5, sum_len([s.as_slice()]));
}
#[test]
fn test_str_from_utf8_owned() {
let xs = Vec::from_slice(b"hello");
- assert_eq!(from_utf8_owned(xs), Ok("hello".to_string()));
+ assert_eq!(from_utf8_owned(xs), Ok(String::from_str("hello")));
let xs = Vec::from_slice("ศไทย中华Việt Nam".as_bytes());
- assert_eq!(from_utf8_owned(xs), Ok("ศไทย中华Việt Nam".to_string()));
+ assert_eq!(from_utf8_owned(xs), Ok(String::from_str("ศไทย中华Việt Nam")));
let xs = Vec::from_slice(b"hello\xFF");
assert_eq!(from_utf8_owned(xs),
assert_eq!(from_utf8_lossy(xs), Slice("ศไทย中华Việt Nam"));
let xs = b"Hello\xC2 There\xFF Goodbye";
- assert_eq!(from_utf8_lossy(xs), Owned("Hello\uFFFD There\uFFFD Goodbye".to_string()));
+ assert_eq!(from_utf8_lossy(xs), Owned(String::from_str("Hello\uFFFD There\uFFFD Goodbye")));
let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
- assert_eq!(from_utf8_lossy(xs), Owned("Hello\uFFFD\uFFFD There\uFFFD Goodbye".to_string()));
+ assert_eq!(from_utf8_lossy(xs),
+ Owned(String::from_str("Hello\uFFFD\uFFFD There\uFFFD Goodbye")));
let xs = b"\xF5foo\xF5\x80bar";
- assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFD\uFFFDbar".to_string()));
+ assert_eq!(from_utf8_lossy(xs), Owned(String::from_str("\uFFFDfoo\uFFFD\uFFFDbar")));
let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
- assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFDbar\uFFFDbaz".to_string()));
+ assert_eq!(from_utf8_lossy(xs), Owned(String::from_str("\uFFFDfoo\uFFFDbar\uFFFDbaz")));
let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
- assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFDbar\uFFFD\uFFFDbaz".to_string()));
+ assert_eq!(from_utf8_lossy(xs),
+ Owned(String::from_str("\uFFFDfoo\uFFFDbar\uFFFD\uFFFDbaz")));
let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
- assert_eq!(from_utf8_lossy(xs), Owned("\uFFFD\uFFFD\uFFFD\uFFFD\
- foo\U00010000bar".to_string()));
+ assert_eq!(from_utf8_lossy(xs), Owned(String::from_str("\uFFFD\uFFFD\uFFFD\uFFFD\
+ foo\U00010000bar")));
// surrogates
let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
- assert_eq!(from_utf8_lossy(xs), Owned("\uFFFD\uFFFD\uFFFDfoo\
- \uFFFD\uFFFD\uFFFDbar".to_string()));
- }
-
- #[test]
- fn test_from_str() {
- let owned: Option<::std::string::String> = from_str("string");
- assert_eq!(owned.as_ref().map(|s| s.as_slice()), Some("string"));
+ assert_eq!(from_utf8_lossy(xs), Owned(String::from_str("\uFFFD\uFFFD\uFFFDfoo\
+ \uFFFD\uFFFD\uFFFDbar")));
}
#[test]
let s = Slice("abcde");
assert_eq!(s.len(), 5);
assert_eq!(s.as_slice(), "abcde");
- assert_eq!(s.to_str().as_slice(), "abcde");
+ assert_eq!(String::from_str(s.as_slice()).as_slice(), "abcde");
assert_eq!(format!("{}", s).as_slice(), "abcde");
- assert!(s.lt(&Owned("bcdef".to_string())));
+ assert!(s.lt(&Owned(String::from_str("bcdef"))));
assert_eq!(Slice(""), Default::default());
- let o = Owned("abcde".to_string());
+ let o = Owned(String::from_str("abcde"));
assert_eq!(o.len(), 5);
assert_eq!(o.as_slice(), "abcde");
- assert_eq!(o.to_str().as_slice(), "abcde");
+ assert_eq!(String::from_str(o.as_slice()).as_slice(), "abcde");
assert_eq!(format!("{}", o).as_slice(), "abcde");
assert!(o.lt(&Slice("bcdef")));
- assert_eq!(Owned("".to_string()), Default::default());
+ assert_eq!(Owned(String::from_str("")), Default::default());
assert!(s.cmp(&o) == Equal);
assert!(s.equiv(&o));
assert!(s.is_slice());
assert!(!s.is_owned());
- let o = Owned("abcde".to_string());
+ let o = Owned(String::from_str("abcde"));
assert!(!o.is_slice());
assert!(o.is_owned());
}
#[test]
fn test_maybe_owned_clone() {
- assert_eq!(Owned("abcde".to_string()), Slice("abcde").clone());
- assert_eq!(Owned("abcde".to_string()), Owned("abcde".to_string()).clone());
+ assert_eq!(Owned(String::from_str("abcde")), Slice("abcde").clone());
+ assert_eq!(Owned(String::from_str("abcde")), Owned(String::from_str("abcde")).clone());
assert_eq!(Slice("abcde"), Slice("abcde").clone());
- assert_eq!(Slice("abcde"), Owned("abcde".to_string()).clone());
+ assert_eq!(Slice("abcde"), Owned(String::from_str("abcde")).clone());
}
#[test]
fn test_maybe_owned_into_string() {
- assert_eq!(Slice("abcde").into_string(), "abcde".to_string());
- assert_eq!(Owned("abcde".to_string()).into_string(), "abcde".to_string());
+ assert_eq!(Slice("abcde").into_string(), String::from_str("abcde"));
+ assert_eq!(Owned(String::from_str("abcde")).into_string(),
+ String::from_str("abcde"));
}
#[test]
fn test_into_maybe_owned() {
assert_eq!("abcde".into_maybe_owned(), Slice("abcde"));
- assert_eq!(("abcde".to_string()).into_maybe_owned(), Slice("abcde"));
- assert_eq!("abcde".into_maybe_owned(), Owned("abcde".to_string()));
- assert_eq!(("abcde".to_string()).into_maybe_owned(), Owned("abcde".to_string()));
+ assert_eq!((String::from_str("abcde")).into_maybe_owned(), Slice("abcde"));
+ assert_eq!("abcde".into_maybe_owned(), Owned(String::from_str("abcde")));
+ assert_eq!((String::from_str("abcde")).into_maybe_owned(),
+ Owned(String::from_str("abcde")));
}
}
mod bench {
use test::Bencher;
use super::*;
- use std::prelude::*;
+ use vec::Vec;
+ use std::iter::{Iterator, DoubleEndedIterator};
+ use std::collections::Collection;
+ use std::slice::Vector;
#[bench]
fn char_iterator(b: &mut Bencher) {
/// Appends a byte to this string buffer. The caller must preserve the valid UTF-8 property.
#[inline]
pub unsafe fn push_byte(&mut self, byte: u8) {
- self.push_bytes([byte])
+ self.vec.push(byte)
}
/// Removes the last byte from the string buffer and returns it. Returns `None` if this string
impl<S: Str> Add<S, String> for String {
fn add(&self, other: &S) -> String {
- let mut s = self.to_string();
+ let mut s = String::from_str(self.as_slice());
s.push_str(other.as_slice());
return s;
}
use str::{Str, StrSlice};
use super::String;
+ #[test]
+ fn test_from_str() {
+ let owned: Option<::std::string::String> = from_str("string");
+ assert_eq!(owned.as_ref().map(|s| s.as_slice()), Some("string"));
+ }
+
#[bench]
fn bench_with_capacity(b: &mut Bencher) {
b.iter(|| {
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use core::default::Default;
use core::fmt;
use core::fmt::Show;
use core::iter;
use core::mem::{replace, swap};
use core::ptr;
+use std::hash::{Writer, Hash};
use {Collection, Mutable, Set, MutableSet, MutableMap, Map};
use vec::Vec;
}
impl<K: Ord, V> Map<K, V> for TreeMap<K, V> {
+ // See comments on tree_find_with
+ #[inline]
fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
- let mut current: &'a Option<Box<TreeNode<K, V>>> = &self.root;
- loop {
- match *current {
- Some(ref r) => {
- match key.cmp(&r.key) {
- Less => current = &r.left,
- Greater => current = &r.right,
- Equal => return Some(&r.value)
- }
- }
- None => return None
- }
- }
+ tree_find_with(&self.root, |k2| key.cmp(k2))
}
}
impl<K: Ord, V> MutableMap<K, V> for TreeMap<K, V> {
+ // See comments on def_tree_find_mut_with
#[inline]
fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
- find_mut(&mut self.root, key)
+ tree_find_mut_with(&mut self.root, |x| key.cmp(x))
}
fn swap(&mut self, key: K, value: V) -> Option<V> {
}
}
+impl<K, V> TreeMap<K, V> {
+ /// Return the value for which f(key) returns Equal. f is invoked
+ /// with current key and helps to navigate the tree
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::ascii::StrAsciiExt;
+ ///
+ /// let mut t = collections::treemap::TreeMap::new();
+ /// t.insert("Content-Type", "application/xml");
+ /// t.insert("User-Agent", "Curl-Rust/0.1");
+ ///
+ /// let ua_key = "user-agent";
+ /// let ua = t.find_with(|&k| {
+ /// ua_key.cmp(&k.to_ascii_lower().as_slice())
+ /// });
+ ///
+ /// assert_eq!(*ua.unwrap(), "Curl-Rust/0.1");
+ /// ```
+ #[inline]
+ pub fn find_with<'a>(&'a self, f:|&K| -> Ordering) -> Option<&'a V> {
+ tree_find_with(&self.root, f)
+ }
+
+ /// Return the value for which f(key) returns Equal. f is invoked
+ /// with current key and helps to navigate the tree
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let mut t = collections::treemap::TreeMap::new();
+ /// t.insert("Content-Type", "application/xml");
+ /// t.insert("User-Agent", "Curl-Rust/0.1");
+ ///
+ /// let new_ua = "Safari/156.0";
+ /// match t.find_mut_with(|k| "User-Agent".cmp(k)) {
+ /// Some(x) => *x = new_ua,
+ /// None => fail!(),
+ /// }
+ ///
+ /// assert_eq!(t.find(&"User-Agent"), Some(&new_ua));
+ /// ```
+ #[inline]
+ pub fn find_mut_with<'a>(&'a mut self, f:|&K| -> Ordering) -> Option<&'a mut V> {
+ tree_find_mut_with(&mut self.root, f)
+ }
+}
+
// range iterators.
macro_rules! bound_setup {
// initialiser of the iterator to manipulate
- ($iter:expr,
+ ($iter:expr, $k:expr,
// whether we are looking for the lower or upper bound.
$is_lower_bound:expr) => {
{
loop {
if !iter.node.is_null() {
let node_k = unsafe {&(*iter.node).key};
- match k.cmp(node_k) {
+ match $k.cmp(node_k) {
Less => iter.traverse_left(),
Greater => iter.traverse_right(),
Equal => {
/// Return a lazy iterator to the first key-value pair whose key is not less than `k`
/// If all keys in map are less than `k` an empty iterator is returned.
pub fn lower_bound<'a>(&'a self, k: &K) -> Entries<'a, K, V> {
- bound_setup!(self.iter_for_traversal(), true)
+ bound_setup!(self.iter_for_traversal(), k, true)
}
/// Return a lazy iterator to the first key-value pair whose key is greater than `k`
/// If all keys in map are not greater than `k` an empty iterator is returned.
pub fn upper_bound<'a>(&'a self, k: &K) -> Entries<'a, K, V> {
- bound_setup!(self.iter_for_traversal(), false)
+ bound_setup!(self.iter_for_traversal(), k, false)
}
/// Get a lazy iterator that should be initialized using
/// If all keys in map are less than `k` an empty iterator is
/// returned.
pub fn mut_lower_bound<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> {
- bound_setup!(self.mut_iter_for_traversal(), true)
+ bound_setup!(self.mut_iter_for_traversal(), k, true)
}
/// Return a lazy iterator to the first key-value pair (with the
/// If all keys in map are not greater than `k` an empty iterator
/// is returned.
pub fn mut_upper_bound<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> {
- bound_setup!(self.mut_iter_for_traversal(), false)
+ bound_setup!(self.mut_iter_for_traversal(), k, false)
}
}
}
}
-fn find_mut<'r, K: Ord, V>(node: &'r mut Option<Box<TreeNode<K, V>>>,
- key: &K)
- -> Option<&'r mut V> {
- match *node {
- Some(ref mut x) => {
- match key.cmp(&x.key) {
- Less => find_mut(&mut x.left, key),
- Greater => find_mut(&mut x.right, key),
- Equal => Some(&mut x.value),
+// Next 2 functions have the same conventions
+//
+// The only difference is that non-mutable version uses loop instead
+// of recursion (performance considerations)
+// It seems to be impossible to avoid recursion with mutability
+//
+// So convention is that comparator is gets at input current key
+// and returns search_key cmp cur_key (i.e. search_key.cmp(cur_key))
+fn tree_find_with<'r, K, V>(node: &'r Option<Box<TreeNode<K, V>>>,
+ f: |&K| -> Ordering) -> Option<&'r V> {
+ let mut current: &'r Option<Box<TreeNode<K, V>>> = node;
+ loop {
+ match *current {
+ Some(ref r) => {
+ match f(&r.key) {
+ Less => current = &r.left,
+ Greater => current = &r.right,
+ Equal => return Some(&r.value)
+ }
+ }
+ None => return None
+ }
+ }
+}
+
+// See comments above tree_find_with
+fn tree_find_mut_with<'r, K, V>(node: &'r mut Option<Box<TreeNode<K, V>>>,
+ f: |&K| -> Ordering) -> Option<&'r mut V> {
+
+ let mut current = node;
+ loop {
+ let temp = current; // hack to appease borrowck
+ match *temp {
+ Some(ref mut r) => {
+ match f(&r.key) {
+ Less => current = &mut r.left,
+ Greater => current = &mut r.right,
+ Equal => return Some(&mut r.value)
+ }
+ }
+ None => return None
}
- }
- None => None
}
}
}
}
+impl<S: Writer, K: Ord + Hash<S>, V: Hash<S>> Hash<S> for TreeMap<K, V> {
+ fn hash(&self, state: &mut S) {
+ for elt in self.iter() {
+ elt.hash(state);
+ }
+ }
+}
+
impl<T: Ord> FromIterator<T> for TreeSet<T> {
fn from_iter<Iter: Iterator<T>>(iter: Iter) -> TreeSet<T> {
let mut set = TreeSet::new();
}
}
+impl<S: Writer, T: Ord + Hash<S>> Hash<S> for TreeSet<T> {
+ fn hash(&self, state: &mut S) {
+ for elt in self.iter() {
+ elt.hash(state);
+ }
+ }
+}
+
#[cfg(test)]
mod test_treemap {
use std::prelude::*;
assert_eq!(m.find(&2), None);
}
+ #[test]
+ fn find_with_empty() {
+ let m: TreeMap<&'static str,int> = TreeMap::new();
+ assert!(m.find_with(|k| "test".cmp(k)) == None);
+ }
+
+ #[test]
+ fn find_with_not_found() {
+ let mut m = TreeMap::new();
+ assert!(m.insert("test1", 2i));
+ assert!(m.insert("test2", 3i));
+ assert!(m.insert("test3", 3i));
+ assert_eq!(m.find_with(|k| "test4".cmp(k)), None);
+ }
+
+ #[test]
+ fn find_with_found() {
+ let mut m = TreeMap::new();
+ assert!(m.insert("test1", 2i));
+ assert!(m.insert("test2", 3i));
+ assert!(m.insert("test3", 4i));
+ assert_eq!(m.find_with(|k| "test2".cmp(k)), Some(&3i));
+ }
+
#[test]
fn test_find_mut() {
let mut m = TreeMap::new();
assert_eq!(m.find(&5), Some(&new));
}
+ #[test]
+ fn test_find_with_mut() {
+ let mut m = TreeMap::new();
+ assert!(m.insert("t1", 12i));
+ assert!(m.insert("t2", 8));
+ assert!(m.insert("t5", 14));
+ let new = 100;
+ match m.find_mut_with(|k| "t5".cmp(k)) {
+ None => fail!(), Some(x) => *x = new
+ }
+ assert_eq!(m.find_with(|k| "t5".cmp(k)), Some(&new));
+ }
+
#[test]
fn insert_replace() {
let mut m = TreeMap::new();
#[cfg(test)]
mod test_set {
use std::prelude::*;
+ use std::hash;
use {Set, MutableSet, Mutable, MutableMap};
use super::{TreeMap, TreeSet};
assert!(m.clone() == m);
}
+ #[test]
+ fn test_hash() {
+ let mut x = TreeSet::new();
+ let mut y = TreeSet::new();
+
+ x.insert(1i);
+ x.insert(2);
+ x.insert(3);
+
+ y.insert(3i);
+ y.insert(2);
+ y.insert(1);
+
+ assert!(hash::hash(&x) == hash::hash(&y));
+ }
+
fn check(a: &[int],
b: &[int],
expected: &[int],
#[test]
fn test_intersection() {
fn check_intersection(a: &[int], b: &[int], expected: &[int]) {
- check(a, b, expected, |x, y, f| x.intersection(y).advance(f))
+ check(a, b, expected, |x, y, f| x.intersection(y).all(f))
}
check_intersection([], [], []);
#[test]
fn test_difference() {
fn check_difference(a: &[int], b: &[int], expected: &[int]) {
- check(a, b, expected, |x, y, f| x.difference(y).advance(f))
+ check(a, b, expected, |x, y, f| x.difference(y).all(f))
}
check_difference([], [], []);
fn test_symmetric_difference() {
fn check_symmetric_difference(a: &[int], b: &[int],
expected: &[int]) {
- check(a, b, expected, |x, y, f| x.symmetric_difference(y).advance(f))
+ check(a, b, expected, |x, y, f| x.symmetric_difference(y).all(f))
}
check_symmetric_difference([], [], []);
fn test_union() {
fn check_union(a: &[int], b: &[int],
expected: &[int]) {
- check(a, b, expected, |x, y, f| x.union(y).advance(f))
+ check(a, b, expected, |x, y, f| x.union(y).all(f))
}
check_union([], [], []);
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use core::default::Default;
use core::mem::zeroed;
use core::mem;
+++ /dev/null
-// Copyright 2012-2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly
-
-#![allow(missing_doc, non_uppercase_statics)]
-
-pub mod normalization {
- use core::prelude::*;
-
- fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
- match r.bsearch(|&(lo, hi, _)| {
- if lo <= c && c <= hi { Equal }
- else if hi < c { Less }
- else { Greater }
- }) {
- Some(idx) => {
- let (_, _, result) = r[idx];
- result
- }
- None => 0
- }
- }
-
-
- static combining_class_table : &'static [(char, char, u8)] = &[
- ('\u0300', '\u0314', 230), ('\u0315', '\u0315', 232),
- ('\u0316', '\u0319', 220), ('\u031a', '\u031a', 232),
- ('\u031b', '\u031b', 216), ('\u031c', '\u0320', 220),
- ('\u0321', '\u0322', 202), ('\u0323', '\u0326', 220),
- ('\u0327', '\u0328', 202), ('\u0329', '\u0333', 220),
- ('\u0334', '\u0338', 1), ('\u0339', '\u033c', 220),
- ('\u033d', '\u0344', 230), ('\u0345', '\u0345', 240),
- ('\u0346', '\u0346', 230), ('\u0347', '\u0349', 220),
- ('\u034a', '\u034c', 230), ('\u034d', '\u034e', 220),
- ('\u0350', '\u0352', 230), ('\u0353', '\u0356', 220),
- ('\u0357', '\u0357', 230), ('\u0358', '\u0358', 232),
- ('\u0359', '\u035a', 220), ('\u035b', '\u035b', 230),
- ('\u035c', '\u035c', 233), ('\u035d', '\u035e', 234),
- ('\u035f', '\u035f', 233), ('\u0360', '\u0361', 234),
- ('\u0362', '\u0362', 233), ('\u0363', '\u036f', 230),
- ('\u0483', '\u0487', 230), ('\u0591', '\u0591', 220),
- ('\u0592', '\u0595', 230), ('\u0596', '\u0596', 220),
- ('\u0597', '\u0599', 230), ('\u059a', '\u059a', 222),
- ('\u059b', '\u059b', 220), ('\u059c', '\u05a1', 230),
- ('\u05a2', '\u05a7', 220), ('\u05a8', '\u05a9', 230),
- ('\u05aa', '\u05aa', 220), ('\u05ab', '\u05ac', 230),
- ('\u05ad', '\u05ad', 222), ('\u05ae', '\u05ae', 228),
- ('\u05af', '\u05af', 230), ('\u05b0', '\u05b0', 10),
- ('\u05b1', '\u05b1', 11), ('\u05b2', '\u05b2', 12),
- ('\u05b3', '\u05b3', 13), ('\u05b4', '\u05b4', 14),
- ('\u05b5', '\u05b5', 15), ('\u05b6', '\u05b6', 16),
- ('\u05b7', '\u05b7', 17), ('\u05b8', '\u05b8', 18),
- ('\u05b9', '\u05ba', 19), ('\u05bb', '\u05bb', 20),
- ('\u05bc', '\u05bc', 21), ('\u05bd', '\u05bd', 22),
- ('\u05bf', '\u05bf', 23), ('\u05c1', '\u05c1', 24),
- ('\u05c2', '\u05c2', 25), ('\u05c4', '\u05c4', 230),
- ('\u05c5', '\u05c5', 220), ('\u05c7', '\u05c7', 18),
- ('\u0610', '\u0617', 230), ('\u0618', '\u0618', 30),
- ('\u0619', '\u0619', 31), ('\u061a', '\u061a', 32),
- ('\u064b', '\u064b', 27), ('\u064c', '\u064c', 28),
- ('\u064d', '\u064d', 29), ('\u064e', '\u064e', 30),
- ('\u064f', '\u064f', 31), ('\u0650', '\u0650', 32),
- ('\u0651', '\u0651', 33), ('\u0652', '\u0652', 34),
- ('\u0653', '\u0654', 230), ('\u0655', '\u0656', 220),
- ('\u0657', '\u065b', 230), ('\u065c', '\u065c', 220),
- ('\u065d', '\u065e', 230), ('\u065f', '\u065f', 220),
- ('\u0670', '\u0670', 35), ('\u06d6', '\u06dc', 230),
- ('\u06df', '\u06e2', 230), ('\u06e3', '\u06e3', 220),
- ('\u06e4', '\u06e4', 230), ('\u06e7', '\u06e8', 230),
- ('\u06ea', '\u06ea', 220), ('\u06eb', '\u06ec', 230),
- ('\u06ed', '\u06ed', 220), ('\u0711', '\u0711', 36),
- ('\u0730', '\u0730', 230), ('\u0731', '\u0731', 220),
- ('\u0732', '\u0733', 230), ('\u0734', '\u0734', 220),
- ('\u0735', '\u0736', 230), ('\u0737', '\u0739', 220),
- ('\u073a', '\u073a', 230), ('\u073b', '\u073c', 220),
- ('\u073d', '\u073d', 230), ('\u073e', '\u073e', 220),
- ('\u073f', '\u0741', 230), ('\u0742', '\u0742', 220),
- ('\u0743', '\u0743', 230), ('\u0744', '\u0744', 220),
- ('\u0745', '\u0745', 230), ('\u0746', '\u0746', 220),
- ('\u0747', '\u0747', 230), ('\u0748', '\u0748', 220),
- ('\u0749', '\u074a', 230), ('\u07eb', '\u07f1', 230),
- ('\u07f2', '\u07f2', 220), ('\u07f3', '\u07f3', 230),
- ('\u0816', '\u0819', 230), ('\u081b', '\u0823', 230),
- ('\u0825', '\u0827', 230), ('\u0829', '\u082d', 230),
- ('\u0859', '\u085b', 220), ('\u08e4', '\u08e5', 230),
- ('\u08e6', '\u08e6', 220), ('\u08e7', '\u08e8', 230),
- ('\u08e9', '\u08e9', 220), ('\u08ea', '\u08ec', 230),
- ('\u08ed', '\u08ef', 220), ('\u08f0', '\u08f0', 27),
- ('\u08f1', '\u08f1', 28), ('\u08f2', '\u08f2', 29),
- ('\u08f3', '\u08f5', 230), ('\u08f6', '\u08f6', 220),
- ('\u08f7', '\u08f8', 230), ('\u08f9', '\u08fa', 220),
- ('\u08fb', '\u08fe', 230), ('\u093c', '\u093c', 7),
- ('\u094d', '\u094d', 9), ('\u0951', '\u0951', 230),
- ('\u0952', '\u0952', 220), ('\u0953', '\u0954', 230),
- ('\u09bc', '\u09bc', 7), ('\u09cd', '\u09cd', 9),
- ('\u0a3c', '\u0a3c', 7), ('\u0a4d', '\u0a4d', 9),
- ('\u0abc', '\u0abc', 7), ('\u0acd', '\u0acd', 9),
- ('\u0b3c', '\u0b3c', 7), ('\u0b4d', '\u0b4d', 9),
- ('\u0bcd', '\u0bcd', 9), ('\u0c4d', '\u0c4d', 9),
- ('\u0c55', '\u0c55', 84), ('\u0c56', '\u0c56', 91),
- ('\u0cbc', '\u0cbc', 7), ('\u0ccd', '\u0ccd', 9),
- ('\u0d4d', '\u0d4d', 9), ('\u0dca', '\u0dca', 9),
- ('\u0e38', '\u0e39', 103), ('\u0e3a', '\u0e3a', 9),
- ('\u0e48', '\u0e4b', 107), ('\u0eb8', '\u0eb9', 118),
- ('\u0ec8', '\u0ecb', 122), ('\u0f18', '\u0f19', 220),
- ('\u0f35', '\u0f35', 220), ('\u0f37', '\u0f37', 220),
- ('\u0f39', '\u0f39', 216), ('\u0f71', '\u0f71', 129),
- ('\u0f72', '\u0f72', 130), ('\u0f74', '\u0f74', 132),
- ('\u0f7a', '\u0f7d', 130), ('\u0f80', '\u0f80', 130),
- ('\u0f82', '\u0f83', 230), ('\u0f84', '\u0f84', 9),
- ('\u0f86', '\u0f87', 230), ('\u0fc6', '\u0fc6', 220),
- ('\u1037', '\u1037', 7), ('\u1039', '\u103a', 9),
- ('\u108d', '\u108d', 220), ('\u135d', '\u135f', 230),
- ('\u1714', '\u1714', 9), ('\u1734', '\u1734', 9),
- ('\u17d2', '\u17d2', 9), ('\u17dd', '\u17dd', 230),
- ('\u18a9', '\u18a9', 228), ('\u1939', '\u1939', 222),
- ('\u193a', '\u193a', 230), ('\u193b', '\u193b', 220),
- ('\u1a17', '\u1a17', 230), ('\u1a18', '\u1a18', 220),
- ('\u1a60', '\u1a60', 9), ('\u1a75', '\u1a7c', 230),
- ('\u1a7f', '\u1a7f', 220), ('\u1b34', '\u1b34', 7),
- ('\u1b44', '\u1b44', 9), ('\u1b6b', '\u1b6b', 230),
- ('\u1b6c', '\u1b6c', 220), ('\u1b6d', '\u1b73', 230),
- ('\u1baa', '\u1bab', 9), ('\u1be6', '\u1be6', 7),
- ('\u1bf2', '\u1bf3', 9), ('\u1c37', '\u1c37', 7),
- ('\u1cd0', '\u1cd2', 230), ('\u1cd4', '\u1cd4', 1),
- ('\u1cd5', '\u1cd9', 220), ('\u1cda', '\u1cdb', 230),
- ('\u1cdc', '\u1cdf', 220), ('\u1ce0', '\u1ce0', 230),
- ('\u1ce2', '\u1ce8', 1), ('\u1ced', '\u1ced', 220),
- ('\u1cf4', '\u1cf4', 230), ('\u1dc0', '\u1dc1', 230),
- ('\u1dc2', '\u1dc2', 220), ('\u1dc3', '\u1dc9', 230),
- ('\u1dca', '\u1dca', 220), ('\u1dcb', '\u1dcc', 230),
- ('\u1dcd', '\u1dcd', 234), ('\u1dce', '\u1dce', 214),
- ('\u1dcf', '\u1dcf', 220), ('\u1dd0', '\u1dd0', 202),
- ('\u1dd1', '\u1de6', 230), ('\u1dfc', '\u1dfc', 233),
- ('\u1dfd', '\u1dfd', 220), ('\u1dfe', '\u1dfe', 230),
- ('\u1dff', '\u1dff', 220), ('\u20d0', '\u20d1', 230),
- ('\u20d2', '\u20d3', 1), ('\u20d4', '\u20d7', 230),
- ('\u20d8', '\u20da', 1), ('\u20db', '\u20dc', 230),
- ('\u20e1', '\u20e1', 230), ('\u20e5', '\u20e6', 1),
- ('\u20e7', '\u20e7', 230), ('\u20e8', '\u20e8', 220),
- ('\u20e9', '\u20e9', 230), ('\u20ea', '\u20eb', 1),
- ('\u20ec', '\u20ef', 220), ('\u20f0', '\u20f0', 230),
- ('\u2cef', '\u2cf1', 230), ('\u2d7f', '\u2d7f', 9),
- ('\u2de0', '\u2dff', 230), ('\u302a', '\u302a', 218),
- ('\u302b', '\u302b', 228), ('\u302c', '\u302c', 232),
- ('\u302d', '\u302d', 222), ('\u302e', '\u302f', 224),
- ('\u3099', '\u309a', 8), ('\ua66f', '\ua66f', 230),
- ('\ua674', '\ua67d', 230), ('\ua69f', '\ua69f', 230),
- ('\ua6f0', '\ua6f1', 230), ('\ua806', '\ua806', 9),
- ('\ua8c4', '\ua8c4', 9), ('\ua8e0', '\ua8f1', 230),
- ('\ua92b', '\ua92d', 220), ('\ua953', '\ua953', 9),
- ('\ua9b3', '\ua9b3', 7), ('\ua9c0', '\ua9c0', 9),
- ('\uaab0', '\uaab0', 230), ('\uaab2', '\uaab3', 230),
- ('\uaab4', '\uaab4', 220), ('\uaab7', '\uaab8', 230),
- ('\uaabe', '\uaabf', 230), ('\uaac1', '\uaac1', 230),
- ('\uaaf6', '\uaaf6', 9), ('\uabed', '\uabed', 9),
- ('\ufb1e', '\ufb1e', 26), ('\ufe20', '\ufe26', 230),
- ('\U000101fd', '\U000101fd', 220), ('\U00010a0d', '\U00010a0d', 220),
- ('\U00010a0f', '\U00010a0f', 230), ('\U00010a38', '\U00010a38', 230),
- ('\U00010a39', '\U00010a39', 1), ('\U00010a3a', '\U00010a3a', 220),
- ('\U00010a3f', '\U00010a3f', 9), ('\U00011046', '\U00011046', 9),
- ('\U000110b9', '\U000110b9', 9), ('\U000110ba', '\U000110ba', 7),
- ('\U00011100', '\U00011102', 230), ('\U00011133', '\U00011134', 9),
- ('\U000111c0', '\U000111c0', 9), ('\U000116b6', '\U000116b6', 9),
- ('\U000116b7', '\U000116b7', 7), ('\U0001d165', '\U0001d166', 216),
- ('\U0001d167', '\U0001d169', 1), ('\U0001d16d', '\U0001d16d', 226),
- ('\U0001d16e', '\U0001d172', 216), ('\U0001d17b', '\U0001d182', 220),
- ('\U0001d185', '\U0001d189', 230), ('\U0001d18a', '\U0001d18b', 220),
- ('\U0001d1aa', '\U0001d1ad', 230), ('\U0001d242', '\U0001d244', 230)
- ];
-
- pub fn canonical_combining_class(c: char) -> u8 {
- bsearch_range_value_table(c, combining_class_table)
- }
-}
use slice::{MutableOrdVector, MutableVectorAllocating, CloneableVector};
use slice::{Items, MutItems};
+
+#[doc(hidden)]
+pub static PTR_MARKER: u8 = 0;
+
/// An owned, growable vector.
///
/// # Examples
/// ```
#[inline]
pub fn new() -> Vec<T> {
- Vec { len: 0, cap: 0, ptr: 0 as *mut T }
+ // We want ptr to never be NULL so instead we set it to some arbitrary
+ // non-null value which is fine since we never call deallocate on the ptr
+ // if cap is 0. The reason for this is because the pointer of a slice
+ // being NULL would break the null pointer optimization for enums.
+ Vec { len: 0, cap: 0, ptr: &PTR_MARKER as *const _ as *mut T }
}
/// Constructs a new, empty `Vec` with the specified capacity.
#[inline]
pub fn with_capacity(capacity: uint) -> Vec<T> {
if mem::size_of::<T>() == 0 {
- Vec { len: 0, cap: uint::MAX, ptr: 0 as *mut T }
+ Vec { len: 0, cap: uint::MAX, ptr: &PTR_MARKER as *const _ as *mut T }
} else if capacity == 0 {
Vec::new()
} else {
/// ```
#[inline]
pub fn from_slice(values: &[T]) -> Vec<T> {
- values.iter().map(|x| x.clone()).collect()
+ let mut vector = Vec::new();
+ vector.push_all(values);
+ vector
}
/// Constructs a `Vec` with copies of a value.
/// ```
#[inline]
pub fn push_all(&mut self, other: &[T]) {
- self.extend(other.iter().map(|e| e.clone()));
+ self.reserve_additional(other.len());
+
+ for i in range(0, other.len()) {
+ let len = self.len();
+
+ // Unsafe code so this can be optimised to a memcpy (or something similarly
+ // fast) when T is Copy. LLVM is easily confused, so any extra operations
+ // during the loop can prevent this optimisation.
+ unsafe {
+ ptr::write(
+ self.as_mut_slice().unsafe_mut_ref(len),
+ other.unsafe_ref(i).clone());
+ self.set_len(len + 1);
+ }
+ }
}
/// Grows the `Vec` in-place.
#[unstable]
impl<T:Clone> Clone for Vec<T> {
fn clone(&self) -> Vec<T> {
- let len = self.len;
- let mut vector = Vec::with_capacity(len);
- // Unsafe code so this can be optimised to a memcpy (or something
- // similarly fast) when T is Copy. LLVM is easily confused, so any
- // extra operations during the loop can prevent this optimisation
- {
- let this_slice = self.as_slice();
- while vector.len < len {
- unsafe {
- let len = vector.len;
- ptr::write(
- vector.as_mut_slice().unsafe_mut_ref(len),
- this_slice.unsafe_ref(len).clone());
- }
- vector.len += 1;
- }
- }
- vector
+ Vec::from_slice(self.as_slice())
}
fn clone_from(&mut self, other: &Vec<T>) {
// self.len <= other.len due to the truncate above, so the
// slice here is always in-bounds.
- let len = self.len();
- self.extend(other.slice_from(len).iter().map(|x| x.clone()));
+ let slice = other.slice_from(self.len());
+ self.push_all(slice);
}
}
/// would also make any pointers to it invalid.
#[inline]
pub fn as_ptr(&self) -> *const T {
- // If we have a 0-sized vector, then the base pointer should not be NULL
- // because an iterator over the slice will attempt to yield the base
- // pointer as the first element in the vector, but this will end up
- // being Some(NULL) which is optimized to None.
- if mem::size_of::<T>() == 0 {
- 1 as *const T
- } else {
- self.ptr as *const T
- }
+ self.ptr as *const T
}
/// Returns a mutable unsafe pointer to the vector's buffer.
/// would also make any pointers to it invalid.
#[inline]
pub fn as_mut_ptr(&mut self) -> *mut T {
- // see above for the 0-size check
- if mem::size_of::<T>() == 0 {
- 1 as *mut T
- } else {
- self.ptr
- }
+ self.ptr
}
/// Retains only the elements specified by the predicate.
}
}
-
#[cfg(test)]
mod tests {
extern crate test;
#[bench]
fn bench_new(b: &mut Bencher) {
b.iter(|| {
- let v: Vec<int> = Vec::new();
+ let v: Vec<uint> = Vec::new();
+ assert_eq!(v.len(), 0);
assert_eq!(v.capacity(), 0);
- assert!(v.as_slice() == []);
})
}
- #[bench]
- fn bench_with_capacity_0(b: &mut Bencher) {
+ fn do_bench_with_capacity(b: &mut Bencher, src_len: uint) {
+ b.bytes = src_len as u64;
+
b.iter(|| {
- let v: Vec<int> = Vec::with_capacity(0);
- assert_eq!(v.capacity(), 0);
- assert!(v.as_slice() == []);
+ let v: Vec<uint> = Vec::with_capacity(src_len);
+ assert_eq!(v.len(), 0);
+ assert_eq!(v.capacity(), src_len);
})
}
+ #[bench]
+ fn bench_with_capacity_0000(b: &mut Bencher) {
+ do_bench_with_capacity(b, 0)
+ }
#[bench]
- fn bench_with_capacity_5(b: &mut Bencher) {
- b.iter(|| {
- let v: Vec<int> = Vec::with_capacity(5);
- assert_eq!(v.capacity(), 5);
- assert!(v.as_slice() == []);
- })
+ fn bench_with_capacity_0010(b: &mut Bencher) {
+ do_bench_with_capacity(b, 10)
+ }
+
+ #[bench]
+ fn bench_with_capacity_0100(b: &mut Bencher) {
+ do_bench_with_capacity(b, 100)
}
#[bench]
- fn bench_with_capacity_100(b: &mut Bencher) {
+ fn bench_with_capacity_1000(b: &mut Bencher) {
+ do_bench_with_capacity(b, 1000)
+ }
+
+ fn do_bench_from_fn(b: &mut Bencher, src_len: uint) {
+ b.bytes = src_len as u64;
+
b.iter(|| {
- let v: Vec<int> = Vec::with_capacity(100);
- assert_eq!(v.capacity(), 100);
- assert!(v.as_slice() == []);
+ let dst = Vec::from_fn(src_len, |i| i);
+ assert_eq!(dst.len(), src_len);
+ assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
})
}
#[bench]
- fn bench_from_fn_0(b: &mut Bencher) {
+ fn bench_from_fn_0000(b: &mut Bencher) {
+ do_bench_from_fn(b, 0)
+ }
+
+ #[bench]
+ fn bench_from_fn_0010(b: &mut Bencher) {
+ do_bench_from_fn(b, 10)
+ }
+
+ #[bench]
+ fn bench_from_fn_0100(b: &mut Bencher) {
+ do_bench_from_fn(b, 100)
+ }
+
+ #[bench]
+ fn bench_from_fn_1000(b: &mut Bencher) {
+ do_bench_from_fn(b, 1000)
+ }
+
+ fn do_bench_from_elem(b: &mut Bencher, src_len: uint) {
+ b.bytes = src_len as u64;
+
b.iter(|| {
- let v: Vec<int> = Vec::from_fn(0, |_| 5);
- assert!(v.as_slice() == []);
+ let dst: Vec<uint> = Vec::from_elem(src_len, 5);
+ assert_eq!(dst.len(), src_len);
+ assert!(dst.iter().all(|x| *x == 5));
})
}
#[bench]
- fn bench_from_fn_5(b: &mut Bencher) {
+ fn bench_from_elem_0000(b: &mut Bencher) {
+ do_bench_from_elem(b, 0)
+ }
+
+ #[bench]
+ fn bench_from_elem_0010(b: &mut Bencher) {
+ do_bench_from_elem(b, 10)
+ }
+
+ #[bench]
+ fn bench_from_elem_0100(b: &mut Bencher) {
+ do_bench_from_elem(b, 100)
+ }
+
+ #[bench]
+ fn bench_from_elem_1000(b: &mut Bencher) {
+ do_bench_from_elem(b, 1000)
+ }
+
+ fn do_bench_from_slice(b: &mut Bencher, src_len: uint) {
+ let src: Vec<uint> = FromIterator::from_iter(range(0, src_len));
+
+ b.bytes = src_len as u64;
+
b.iter(|| {
- let v: Vec<int> = Vec::from_fn(5, |_| 5);
- assert!(v.as_slice() == [5, 5, 5, 5, 5]);
- })
+ let dst = Vec::from_slice(src.clone().as_slice());
+ assert_eq!(dst.len(), src_len);
+ assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+ });
+ }
+
+ #[bench]
+ fn bench_from_slice_0000(b: &mut Bencher) {
+ do_bench_from_slice(b, 0)
+ }
+
+ #[bench]
+ fn bench_from_slice_0010(b: &mut Bencher) {
+ do_bench_from_slice(b, 10)
+ }
+
+ #[bench]
+ fn bench_from_slice_0100(b: &mut Bencher) {
+ do_bench_from_slice(b, 100)
}
#[bench]
- fn bench_from_slice_0(b: &mut Bencher) {
+ fn bench_from_slice_1000(b: &mut Bencher) {
+ do_bench_from_slice(b, 1000)
+ }
+
+ fn do_bench_from_iter(b: &mut Bencher, src_len: uint) {
+ let src: Vec<uint> = FromIterator::from_iter(range(0, src_len));
+
+ b.bytes = src_len as u64;
+
b.iter(|| {
- let v: Vec<int> = Vec::from_slice([]);
- assert!(v.as_slice() == []);
- })
+ let dst: Vec<uint> = FromIterator::from_iter(src.clone().move_iter());
+ assert_eq!(dst.len(), src_len);
+ assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+ });
+ }
+
+ #[bench]
+ fn bench_from_iter_0000(b: &mut Bencher) {
+ do_bench_from_iter(b, 0)
}
#[bench]
- fn bench_from_slice_5(b: &mut Bencher) {
+ fn bench_from_iter_0010(b: &mut Bencher) {
+ do_bench_from_iter(b, 10)
+ }
+
+ #[bench]
+ fn bench_from_iter_0100(b: &mut Bencher) {
+ do_bench_from_iter(b, 100)
+ }
+
+ #[bench]
+ fn bench_from_iter_1000(b: &mut Bencher) {
+ do_bench_from_iter(b, 1000)
+ }
+
+ fn do_bench_extend(b: &mut Bencher, dst_len: uint, src_len: uint) {
+ let dst: Vec<uint> = FromIterator::from_iter(range(0, dst_len));
+ let src: Vec<uint> = FromIterator::from_iter(range(dst_len, dst_len + src_len));
+
+ b.bytes = src_len as u64;
+
b.iter(|| {
- let v: Vec<int> = Vec::from_slice([1i, 2, 3, 4, 5]);
- assert!(v.as_slice() == [1, 2, 3, 4, 5]);
- })
+ let mut dst = dst.clone();
+ dst.extend(src.clone().move_iter());
+ assert_eq!(dst.len(), dst_len + src_len);
+ assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+ });
+ }
+
+ #[bench]
+ fn bench_extend_0000_0000(b: &mut Bencher) {
+ do_bench_extend(b, 0, 0)
+ }
+
+ #[bench]
+ fn bench_extend_0000_0010(b: &mut Bencher) {
+ do_bench_extend(b, 0, 10)
+ }
+
+ #[bench]
+ fn bench_extend_0000_0100(b: &mut Bencher) {
+ do_bench_extend(b, 0, 100)
+ }
+
+ #[bench]
+ fn bench_extend_0000_1000(b: &mut Bencher) {
+ do_bench_extend(b, 0, 1000)
}
#[bench]
- fn bench_from_iter_0(b: &mut Bencher) {
+ fn bench_extend_0010_0010(b: &mut Bencher) {
+ do_bench_extend(b, 10, 10)
+ }
+
+ #[bench]
+ fn bench_extend_0100_0100(b: &mut Bencher) {
+ do_bench_extend(b, 100, 100)
+ }
+
+ #[bench]
+ fn bench_extend_1000_1000(b: &mut Bencher) {
+ do_bench_extend(b, 1000, 1000)
+ }
+
+ fn do_bench_push_all(b: &mut Bencher, dst_len: uint, src_len: uint) {
+ let dst: Vec<uint> = FromIterator::from_iter(range(0, dst_len));
+ let src: Vec<uint> = FromIterator::from_iter(range(dst_len, dst_len + src_len));
+
+ b.bytes = src_len as u64;
+
b.iter(|| {
- let v0: Vec<int> = vec!();
- let v1: Vec<int> = FromIterator::from_iter(v0.move_iter());
- assert!(v1.as_slice() == []);
- })
+ let mut dst = dst.clone();
+ dst.push_all(src.as_slice());
+ assert_eq!(dst.len(), dst_len + src_len);
+ assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+ });
+ }
+
+ #[bench]
+ fn bench_push_all_0000_0000(b: &mut Bencher) {
+ do_bench_push_all(b, 0, 0)
+ }
+
+ #[bench]
+ fn bench_push_all_0000_0010(b: &mut Bencher) {
+ do_bench_push_all(b, 0, 10)
+ }
+
+ #[bench]
+ fn bench_push_all_0000_0100(b: &mut Bencher) {
+ do_bench_push_all(b, 0, 100)
+ }
+
+ #[bench]
+ fn bench_push_all_0000_1000(b: &mut Bencher) {
+ do_bench_push_all(b, 0, 1000)
}
#[bench]
- fn bench_from_iter_5(b: &mut Bencher) {
+ fn bench_push_all_0010_0010(b: &mut Bencher) {
+ do_bench_push_all(b, 10, 10)
+ }
+
+ #[bench]
+ fn bench_push_all_0100_0100(b: &mut Bencher) {
+ do_bench_push_all(b, 100, 100)
+ }
+
+ #[bench]
+ fn bench_push_all_1000_1000(b: &mut Bencher) {
+ do_bench_push_all(b, 1000, 1000)
+ }
+
+ fn do_bench_push_all_move(b: &mut Bencher, dst_len: uint, src_len: uint) {
+ let dst: Vec<uint> = FromIterator::from_iter(range(0u, dst_len));
+ let src: Vec<uint> = FromIterator::from_iter(range(dst_len, dst_len + src_len));
+
+ b.bytes = src_len as u64;
+
b.iter(|| {
- let v0: Vec<int> = vec!(1, 2, 3, 4, 5);
- let v1: Vec<int> = FromIterator::from_iter(v0.move_iter());
- assert!(v1.as_slice() == [1, 2, 3, 4, 5]);
- })
+ let mut dst = dst.clone();
+ dst.push_all_move(src.clone());
+ assert_eq!(dst.len(), dst_len + src_len);
+ assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+ });
+ }
+
+ #[bench]
+ fn bench_push_all_move_0000_0000(b: &mut Bencher) {
+ do_bench_push_all_move(b, 0, 0)
}
#[bench]
- fn bench_extend_0(b: &mut Bencher) {
+ fn bench_push_all_move_0000_0010(b: &mut Bencher) {
+ do_bench_push_all_move(b, 0, 10)
+ }
+
+ #[bench]
+ fn bench_push_all_move_0000_0100(b: &mut Bencher) {
+ do_bench_push_all_move(b, 0, 100)
+ }
+
+ #[bench]
+ fn bench_push_all_move_0000_1000(b: &mut Bencher) {
+ do_bench_push_all_move(b, 0, 1000)
+ }
+
+ #[bench]
+ fn bench_push_all_move_0010_0010(b: &mut Bencher) {
+ do_bench_push_all_move(b, 10, 10)
+ }
+
+ #[bench]
+ fn bench_push_all_move_0100_0100(b: &mut Bencher) {
+ do_bench_push_all_move(b, 100, 100)
+ }
+
+ #[bench]
+ fn bench_push_all_move_1000_1000(b: &mut Bencher) {
+ do_bench_push_all_move(b, 1000, 1000)
+ }
+
+ fn do_bench_clone(b: &mut Bencher, src_len: uint) {
+ let src: Vec<uint> = FromIterator::from_iter(range(0, src_len));
+
+ b.bytes = src_len as u64;
+
b.iter(|| {
- let v0: Vec<int> = vec!();
- let mut v1: Vec<int> = vec!(1, 2, 3, 4, 5);
- v1.extend(v0.move_iter());
- assert!(v1.as_slice() == [1, 2, 3, 4, 5]);
- })
+ let dst = src.clone();
+ assert_eq!(dst.len(), src_len);
+ assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+ });
+ }
+
+ #[bench]
+ fn bench_clone_0000(b: &mut Bencher) {
+ do_bench_clone(b, 0)
+ }
+
+ #[bench]
+ fn bench_clone_0010(b: &mut Bencher) {
+ do_bench_clone(b, 10)
+ }
+
+ #[bench]
+ fn bench_clone_0100(b: &mut Bencher) {
+ do_bench_clone(b, 100)
}
#[bench]
- fn bench_extend_5(b: &mut Bencher) {
+ fn bench_clone_1000(b: &mut Bencher) {
+ do_bench_clone(b, 1000)
+ }
+
+ fn do_bench_clone_from(b: &mut Bencher, times: uint, dst_len: uint, src_len: uint) {
+ let dst: Vec<uint> = FromIterator::from_iter(range(0, src_len));
+ let src: Vec<uint> = FromIterator::from_iter(range(dst_len, dst_len + src_len));
+
+ b.bytes = (times * src_len) as u64;
+
b.iter(|| {
- let v0: Vec<int> = vec!(1, 2, 3, 4, 5);
- let mut v1: Vec<int> = vec!(1, 2, 3, 4, 5);
- v1.extend(v0.move_iter());
- assert!(v1.as_slice() == [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]);
- })
+ let mut dst = dst.clone();
+
+ for _ in range(0, times) {
+ dst.clone_from(&src);
+
+ assert_eq!(dst.len(), src_len);
+ assert!(dst.iter().enumerate().all(|(i, x)| dst_len + i == *x));
+ }
+ });
+ }
+
+ #[bench]
+ fn bench_clone_from_01_0000_0000(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 0, 0)
+ }
+
+ #[bench]
+ fn bench_clone_from_01_0000_0010(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 0, 10)
+ }
+
+ #[bench]
+ fn bench_clone_from_01_0000_0100(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 0, 100)
+ }
+
+ #[bench]
+ fn bench_clone_from_01_0000_1000(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 0, 1000)
+ }
+
+ #[bench]
+ fn bench_clone_from_01_0010_0010(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 10, 10)
+ }
+
+ #[bench]
+ fn bench_clone_from_01_0100_0100(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 100, 100)
+ }
+
+ #[bench]
+ fn bench_clone_from_01_1000_1000(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 1000, 1000)
+ }
+
+ #[bench]
+ fn bench_clone_from_01_0010_0100(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 10, 100)
+ }
+
+ #[bench]
+ fn bench_clone_from_01_0100_1000(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 100, 1000)
+ }
+
+ #[bench]
+ fn bench_clone_from_01_0010_0000(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 10, 0)
+ }
+
+ #[bench]
+ fn bench_clone_from_01_0100_0010(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 100, 10)
+ }
+
+ #[bench]
+ fn bench_clone_from_01_1000_0100(b: &mut Bencher) {
+ do_bench_clone_from(b, 1, 1000, 100)
+ }
+
+ #[bench]
+ fn bench_clone_from_10_0000_0000(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 0, 0)
+ }
+
+ #[bench]
+ fn bench_clone_from_10_0000_0010(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 0, 10)
+ }
+
+ #[bench]
+ fn bench_clone_from_10_0000_0100(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 0, 100)
+ }
+
+ #[bench]
+ fn bench_clone_from_10_0000_1000(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 0, 1000)
+ }
+
+ #[bench]
+ fn bench_clone_from_10_0010_0010(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 10, 10)
+ }
+
+ #[bench]
+ fn bench_clone_from_10_0100_0100(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 100, 100)
+ }
+
+ #[bench]
+ fn bench_clone_from_10_1000_1000(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 1000, 1000)
+ }
+
+ #[bench]
+ fn bench_clone_from_10_0010_0100(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 10, 100)
+ }
+
+ #[bench]
+ fn bench_clone_from_10_0100_1000(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 100, 1000)
+ }
+
+ #[bench]
+ fn bench_clone_from_10_0010_0000(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 10, 0)
+ }
+
+ #[bench]
+ fn bench_clone_from_10_0100_0010(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 100, 10)
+ }
+
+ #[bench]
+ fn bench_clone_from_10_1000_0100(b: &mut Bencher) {
+ do_bench_clone_from(b, 10, 1000, 100)
}
}
//! This module implements the `Any` trait, which enables dynamic typing
//! of any `'static` type through runtime reflection.
//!
-//! `Any` itself can be used to get a `TypeId`, and has more features when used as a trait object.
-//! As `&Any` (a borrowed trait object), it has the `is` and `as_ref` methods, to test if the
-//! contained value is of a given type, and to get a reference to the inner value as a type. As
-//! `&mut Any`, there is also the `as_mut` method, for getting a mutable reference to the inner
-//! value. `Box<Any>` adds the `move` method, which will unwrap a `Box<T>` from the object. See
-//! the extension traits (`*Ext`) for the full details.
+//! `Any` itself can be used to get a `TypeId`, and has more features when used
+//! as a trait object. As `&Any` (a borrowed trait object), it has the `is` and
+//! `as_ref` methods, to test if the contained value is of a given type, and to
+//! get a reference to the inner value as a type. As`&mut Any`, there is also
+//! the `as_mut` method, for getting a mutable reference to the inner value.
+//! `Box<Any>` adds the `move` method, which will unwrap a `Box<T>` from the
+//! object. See the extension traits (`*Ext`) for the full details.
+//!
+//! Note that &Any is limited to testing whether a value is of a specified
+//! concrete type, and cannot be used to test whether a type implements a trait.
+//!
+//! # Examples
+//!
+//! Consider a situation where we want to log out a value passed to a function.
+//! We know the value we're working on implements Show, but we don't know its
+//! concrete type. We want to give special treatment to certain types: in this
+//! case printing out the length of String values prior to their value.
+//! We don't know the concrete type of our value at compile time, so we need to
+//! use runtime reflection instead.
+//!
+//! ```rust
+//! use std::fmt::Show;
+//! use std::any::{Any, AnyRefExt};
+//!
+//! // Logger function for any type that implements Show.
+//! fn log<T: Any+Show>(value: &T) {
+//! let value_any = value as &Any;
+//!
+//! // try to convert our value to a String. If successful, we want to
+//! // output the String's length as well as its value. If not, it's a
+//! // different type: just print it out unadorned.
+//! match value_any.as_ref::<String>() {
+//! Some(as_string) => {
+//! println!("String ({}): {}", as_string.len(), as_string);
+//! }
+//! None => {
+//! println!("{}", value);
+//! }
+//! }
+//! }
+//!
+//! // This function wants to log its parameter out prior to doing work with it.
+//! fn do_work<T: Show>(value: &T) {
+//! log(value);
+//! // ...do some other work
+//! }
+//!
+//! fn main() {
+//! let my_string = "Hello World".to_string();
+//! do_work(&my_string);
+//!
+//! let my_i8: i8 = 100;
+//! do_work(&my_i8);
+//! }
+//! ```
use mem::{transmute, transmute_copy};
use option::{Option, Some, None};
///
/// fn with_lock(spinlock: &Arc<AtomicBool>, f: || -> ()) {
/// // CAS loop until we are able to replace `false` with `true`
- /// while spinlock.compare_and_swap(false, true, SeqCst) == false {
+ /// while spinlock.compare_and_swap(false, true, SeqCst) != false {
/// // Since tasks may not be preemptive (if they are green threads)
/// // yield to the scheduler to let the other task run. Low level
/// // concurrent code needs to take into account Rust's two threading
use ty::Unsafe;
/// A mutable memory location that admits only `Copy` data.
+#[unstable = "likely to be renamed; otherwise stable"]
pub struct Cell<T> {
value: Unsafe<T>,
noshare: marker::NoShare,
}
+#[stable]
impl<T:Copy> Cell<T> {
/// Creates a new `Cell` containing the given value.
pub fn new(value: T) -> Cell<T> {
}
}
-#[unstable]
+#[unstable = "waiting for `Clone` trait to become stable"]
impl<T:Copy> Clone for Cell<T> {
fn clone(&self) -> Cell<T> {
Cell::new(self.get())
}
}
+#[unstable = "waiting for `PartialEq` trait to become stable"]
impl<T:PartialEq + Copy> PartialEq for Cell<T> {
fn eq(&self, other: &Cell<T>) -> bool {
self.get() == other.get()
}
/// A mutable memory location with dynamically checked borrow rules
+#[unstable = "likely to be renamed; otherwise stable"]
pub struct RefCell<T> {
value: Unsafe<T>,
borrow: Cell<BorrowFlag>,
impl<T> RefCell<T> {
/// Create a new `RefCell` containing `value`
+ #[stable]
pub fn new(value: T) -> RefCell<T> {
RefCell {
value: Unsafe::new(value),
}
/// Consumes the `RefCell`, returning the wrapped value.
+ #[unstable = "may be renamed, depending on global conventions"]
pub fn unwrap(self) -> T {
debug_assert!(self.borrow.get() == UNUSED);
unsafe{self.value.unwrap()}
/// immutable borrows can be taken out at the same time.
///
/// Returns `None` if the value is currently mutably borrowed.
+ #[unstable = "may be renamed, depending on global conventions"]
pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
match self.borrow.get() {
WRITING => None,
/// # Failure
///
/// Fails if the value is currently mutably borrowed.
+ #[unstable]
pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
match self.try_borrow() {
Some(ptr) => ptr,
/// cannot be borrowed while this borrow is active.
///
/// Returns `None` if the value is currently borrowed.
+ #[unstable = "may be renamed, depending on global conventions"]
pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
match self.borrow.get() {
UNUSED => {
/// # Failure
///
/// Fails if the value is currently borrowed.
+ #[unstable]
pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
match self.try_borrow_mut() {
Some(ptr) => ptr,
}
}
-#[unstable]
+#[unstable = "waiting for `Clone` to become stable"]
impl<T: Clone> Clone for RefCell<T> {
fn clone(&self) -> RefCell<T> {
RefCell::new(self.borrow().clone())
}
}
+#[unstable = "waiting for `PartialEq` to become stable"]
impl<T: PartialEq> PartialEq for RefCell<T> {
fn eq(&self, other: &RefCell<T>) -> bool {
*self.borrow() == *other.borrow()
}
/// Wraps a borrowed reference to a value in a `RefCell` box.
+#[unstable]
pub struct Ref<'b, T> {
// FIXME #12808: strange name to try to avoid interfering with
// field accesses of the contained type via Deref
}
#[unsafe_destructor]
+#[unstable]
impl<'b, T> Drop for Ref<'b, T> {
fn drop(&mut self) {
let borrow = self._parent.borrow.get();
}
}
+#[unstable = "waiting for `Deref` to become stable"]
impl<'b, T> Deref<T> for Ref<'b, T> {
#[inline]
fn deref<'a>(&'a self) -> &'a T {
///
/// A `Clone` implementation would interfere with the widespread
/// use of `r.borrow().clone()` to clone the contents of a `RefCell`.
-#[experimental]
+#[experimental = "likely to be moved to a method, pending language changes"]
pub fn clone_ref<'b, T>(orig: &Ref<'b, T>) -> Ref<'b, T> {
// Since this Ref exists, we know the borrow flag
// is not set to WRITING.
}
/// Wraps a mutable borrowed reference to a value in a `RefCell` box.
+#[unstable]
pub struct RefMut<'b, T> {
// FIXME #12808: strange name to try to avoid interfering with
// field accesses of the contained type via Deref
}
#[unsafe_destructor]
+#[unstable]
impl<'b, T> Drop for RefMut<'b, T> {
fn drop(&mut self) {
let borrow = self._parent.borrow.get();
}
}
+#[unstable = "waiting for `Deref` to become stable"]
impl<'b, T> Deref<T> for RefMut<'b, T> {
#[inline]
fn deref<'a>(&'a self) -> &'a T {
}
}
+#[unstable = "waiting for `DerefMut` to become stable"]
impl<'b, T> DerefMut<T> for RefMut<'b, T> {
#[inline]
fn deref_mut<'a>(&'a mut self) -> &'a mut T {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-//! Character manipulation (`char` type, Unicode Scalar Value)
+//! Character manipulation.
//!
-//! This module provides the `Char` trait, as well as its implementation
-//! for the primitive `char` type, in order to allow basic character manipulation.
-//!
-//! A `char` actually represents a
-//! *[Unicode Scalar Value](http://www.unicode.org/glossary/#unicode_scalar_value)*,
-//! as it can contain any Unicode code point except high-surrogate and
-//! low-surrogate code points.
-//!
-//! As such, only values in the ranges \[0x0,0xD7FF\] and \[0xE000,0x10FFFF\]
-//! (inclusive) are allowed. A `char` can always be safely cast to a `u32`;
-//! however the converse is not always true due to the above range limits
-//! and, as such, should be performed via the `from_u32` function..
+//! For more details, see ::unicode::char (a.k.a. std::char)
#![allow(non_snake_case_functions)]
#![doc(primitive = "char")]
use mem::transmute;
use option::{None, Option, Some};
use iter::{Iterator, range_step};
-use unicode::{derived_property, property, general_category, conversions};
-
-/// Returns the canonical decomposition of a character.
-pub use unicode::normalization::decompose_canonical;
-/// Returns the compatibility decomposition of a character.
-pub use unicode::normalization::decompose_compatible;
// UTF-8 ranges and tags for encoding characters
static TAG_CONT: u8 = 0b1000_0000u8;
}
}
-/// Returns whether the specified `char` is considered a Unicode alphabetic
-/// code point
-pub fn is_alphabetic(c: char) -> bool { derived_property::Alphabetic(c) }
-
-/// Returns whether the specified `char` satisfies the 'XID_Start' Unicode property
-///
-/// 'XID_Start' is a Unicode Derived Property specified in
-/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
-/// mostly similar to ID_Start but modified for closure under NFKx.
-pub fn is_XID_start(c: char) -> bool { derived_property::XID_Start(c) }
-
-/// Returns whether the specified `char` satisfies the 'XID_Continue' Unicode property
-///
-/// 'XID_Continue' is a Unicode Derived Property specified in
-/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
-/// mostly similar to 'ID_Continue' but modified for closure under NFKx.
-pub fn is_XID_continue(c: char) -> bool { derived_property::XID_Continue(c) }
-
-///
-/// Indicates whether a `char` is in lower case
-///
-/// This is defined according to the terms of the Unicode Derived Core Property 'Lowercase'.
-///
-#[inline]
-pub fn is_lowercase(c: char) -> bool { derived_property::Lowercase(c) }
-
-///
-/// Indicates whether a `char` is in upper case
-///
-/// This is defined according to the terms of the Unicode Derived Core Property 'Uppercase'.
-///
-#[inline]
-pub fn is_uppercase(c: char) -> bool { derived_property::Uppercase(c) }
-
-///
-/// Indicates whether a `char` is whitespace
-///
-/// Whitespace is defined in terms of the Unicode Property 'White_Space'.
-///
-#[inline]
-pub fn is_whitespace(c: char) -> bool {
- // As an optimization ASCII whitespace characters are checked separately
- c == ' '
- || ('\x09' <= c && c <= '\x0d')
- || property::White_Space(c)
-}
-
-///
-/// Indicates whether a `char` is alphanumeric
-///
-/// Alphanumericness is defined in terms of the Unicode General Categories
-/// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
-///
-#[inline]
-pub fn is_alphanumeric(c: char) -> bool {
- derived_property::Alphabetic(c)
- || general_category::Nd(c)
- || general_category::Nl(c)
- || general_category::No(c)
-}
-
-///
-/// Indicates whether a `char` is a control code point
-///
-/// Control code points are defined in terms of the Unicode General Category
-/// 'Cc'.
-///
-#[inline]
-pub fn is_control(c: char) -> bool { general_category::Cc(c) }
-
-/// Indicates whether the `char` is numeric (Nd, Nl, or No)
-#[inline]
-pub fn is_digit(c: char) -> bool {
- general_category::Nd(c)
- || general_category::Nl(c)
- || general_category::No(c)
-}
-
///
/// Checks if a `char` parses as a numeric digit in the given radix
///
else { None }
}
-/// Convert a char to its uppercase equivalent
-///
-/// The case-folding performed is the common or simple mapping:
-/// it maps one unicode codepoint (one char in Rust) to its uppercase equivalent according
-/// to the Unicode database at ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
-/// The additional SpecialCasing.txt is not considered here, as it expands to multiple
-/// codepoints in some cases.
-///
-/// A full reference can be found here
-/// http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G33992
-///
-/// # Return value
-///
-/// Returns the char itself if no conversion was made
-#[inline]
-pub fn to_uppercase(c: char) -> char {
- conversions::to_upper(c)
-}
-
-/// Convert a char to its lowercase equivalent
-///
-/// The case-folding performed is the common or simple mapping
-/// see `to_uppercase` for references and more information
-///
-/// # Return value
-///
-/// Returns the char itself if no conversion if possible
-#[inline]
-pub fn to_lowercase(c: char) -> char {
- conversions::to_lower(c)
-}
-
///
/// Converts a number to the character representing it
///
}
}
-/// Useful functions for Unicode characters.
+/// Basic `char` manipulations.
pub trait Char {
- /// Returns whether the specified character is considered a Unicode
- /// alphabetic code point.
- fn is_alphabetic(&self) -> bool;
-
- /// Returns whether the specified character satisfies the 'XID_Start'
- /// Unicode property.
- ///
- /// 'XID_Start' is a Unicode Derived Property specified in
- /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
- /// mostly similar to ID_Start but modified for closure under NFKx.
- fn is_XID_start(&self) -> bool;
-
- /// Returns whether the specified `char` satisfies the 'XID_Continue'
- /// Unicode property.
- ///
- /// 'XID_Continue' is a Unicode Derived Property specified in
- /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
- /// mostly similar to 'ID_Continue' but modified for closure under NFKx.
- fn is_XID_continue(&self) -> bool;
-
-
- /// Indicates whether a character is in lowercase.
- ///
- /// This is defined according to the terms of the Unicode Derived Core
- /// Property `Lowercase`.
- fn is_lowercase(&self) -> bool;
-
- /// Indicates whether a character is in uppercase.
- ///
- /// This is defined according to the terms of the Unicode Derived Core
- /// Property `Uppercase`.
- fn is_uppercase(&self) -> bool;
-
- /// Indicates whether a character is whitespace.
- ///
- /// Whitespace is defined in terms of the Unicode Property `White_Space`.
- fn is_whitespace(&self) -> bool;
-
- /// Indicates whether a character is alphanumeric.
- ///
- /// Alphanumericness is defined in terms of the Unicode General Categories
- /// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
- fn is_alphanumeric(&self) -> bool;
-
- /// Indicates whether a character is a control code point.
- ///
- /// Control code points are defined in terms of the Unicode General
- /// Category `Cc`.
- fn is_control(&self) -> bool;
-
- /// Indicates whether the character is numeric (Nd, Nl, or No).
- fn is_digit(&self) -> bool;
-
/// Checks if a `char` parses as a numeric digit in the given radix.
///
/// Compared to `is_digit()`, this function only recognizes the characters
/// Fails if given a radix outside the range [0..36].
fn to_digit(&self, radix: uint) -> Option<uint>;
- /// Converts a character to its lowercase equivalent.
- ///
- /// The case-folding performed is the common or simple mapping. See
- /// `to_uppercase()` for references and more information.
- ///
- /// # Return value
- ///
- /// Returns the lowercase equivalent of the character, or the character
- /// itself if no conversion is possible.
- fn to_lowercase(&self) -> char;
-
- /// Converts a character to its uppercase equivalent.
- ///
- /// The case-folding performed is the common or simple mapping: it maps
- /// one unicode codepoint (one character in Rust) to its uppercase
- /// equivalent according to the Unicode database [1]. The additional
- /// `SpecialCasing.txt` is not considered here, as it expands to multiple
- /// codepoints in some cases.
- ///
- /// A full reference can be found here [2].
- ///
- /// # Return value
- ///
- /// Returns the uppercase equivalent of the character, or the character
- /// itself if no conversion was made.
- ///
- /// [1]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
- ///
- /// [2]: http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G33992
- fn to_uppercase(&self) -> char;
-
/// Converts a number to the character representing it.
///
/// # Return value
}
impl Char for char {
- fn is_alphabetic(&self) -> bool { is_alphabetic(*self) }
-
- fn is_XID_start(&self) -> bool { is_XID_start(*self) }
-
- fn is_XID_continue(&self) -> bool { is_XID_continue(*self) }
-
- fn is_lowercase(&self) -> bool { is_lowercase(*self) }
-
- fn is_uppercase(&self) -> bool { is_uppercase(*self) }
-
- fn is_whitespace(&self) -> bool { is_whitespace(*self) }
-
- fn is_alphanumeric(&self) -> bool { is_alphanumeric(*self) }
-
- fn is_control(&self) -> bool { is_control(*self) }
-
- fn is_digit(&self) -> bool { is_digit(*self) }
-
fn is_digit_radix(&self, radix: uint) -> bool { is_digit_radix(*self, radix) }
fn to_digit(&self, radix: uint) -> Option<uint> { to_digit(*self, radix) }
- fn to_lowercase(&self) -> char { to_lowercase(*self) }
-
- fn to_uppercase(&self) -> char { to_uppercase(*self) }
-
fn from_digit(num: uint, radix: uint) -> Option<char> { from_digit(num, radix) }
fn escape_unicode(&self, f: |char|) { escape_unicode(*self, f) }
}
}
}
-
-
//! ```
use option::{Option, Some};
-#[cfg(stage0)]
-use option::None;
/// Trait for values that can be compared for equality and inequality.
///
pub trait PartialOrd: PartialEq {
/// This method returns an ordering between `self` and `other` values
/// if one exists.
- #[cfg(stage0)]
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- match (!self.lt(other), !other.lt(self)) {
- (false, false) => None,
- (false, true) => Some(Less),
- (true, false) => Some(Greater),
- (true, true) => Some(Equal),
- }
- }
-
- /// This method returns an ordering between `self` and `other` values
- /// if one exists.
- #[cfg(not(stage0))]
fn partial_cmp(&self, other: &Self) -> Option<Ordering>;
/// This method tests less than (for `self` and `other`) and is used by the `<` operator.
/**
* Converts a number to its string representation as a byte vector.
* This is meant to be a common base implementation for all numeric string
- * conversion functions like `to_str()` or `to_str_radix()`.
+ * conversion functions like `to_string()` or `to_str_radix()`.
*
* # Arguments
* - `num` - The number to convert. Accepts any number that
/// integer, since the conversion would throw away aliasing information.
pub fn offset<T>(dst: *const T, offset: int) -> *const T;
- /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
- /// a size of `count` * `size_of::<T>()` and an alignment of
- /// `min_align_of::<T>()`
+ /// Copies data from one location to another.
+ ///
+ /// Copies `count` elements (not bytes) from `src` to `dst`. The source
+ /// and destination may *not* overlap.
+ ///
+ /// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
+ ///
+ /// # Example
+ ///
+ /// A safe swap function:
+ ///
+ /// ```
+ /// use std::mem;
+ /// use std::ptr;
+ ///
+ /// fn swap<T>(x: &mut T, y: &mut T) {
+ /// unsafe {
+ /// // Give ourselves some scratch space to work with
+ /// let mut t: T = mem::uninitialized();
+ ///
+ /// // Perform the swap, `&mut` pointers never alias
+ /// ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
+ /// ptr::copy_nonoverlapping_memory(x, &*y, 1);
+ /// ptr::copy_nonoverlapping_memory(y, &t, 1);
+ ///
+ /// // y and t now point to the same thing, but we need to completely forget `tmp`
+ /// // because it's no longer relevant.
+ /// mem::forget(t);
+ /// }
+ /// }
+ /// ```
+ ///
+ /// # Safety Note
+ ///
+ /// If the source and destination overlap then the behavior of this
+ /// function is undefined.
+ #[unstable]
pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint);
- /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with
- /// a size of `count` * `size_of::<T>()` and an alignment of
- /// `min_align_of::<T>()`
+ /// Copies data from one location to another.
+ ///
+ /// Copies `count` elements (not bytes) from `src` to `dst`. The source
+ /// and destination may overlap.
+ ///
+ /// `copy_memory` is semantically equivalent to C's `memmove`.
+ ///
+ /// # Example
+ ///
+ /// Efficiently create a Rust vector from an unsafe buffer:
+ ///
+ /// ```
+ /// use std::ptr;
+ ///
+ /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: uint) -> Vec<T> {
+ /// let mut dst = Vec::with_capacity(elts);
+ /// dst.set_len(elts);
+ /// ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
+ /// dst
+ /// }
+ /// ```
+ ///
+ #[unstable]
pub fn copy_memory<T>(dst: *mut T, src: *const T, count: uint);
- /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
- /// size of `count` * `size_of::<T>()` and an alignment of
- /// `min_align_of::<T>()`
+ /// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
+ /// bytes of memory starting at `dst` to `c`.
+ #[experimental = "uncertain about naming and semantics"]
pub fn set_memory<T>(dst: *mut T, val: u8, count: uint);
/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
*/
+use clone::Clone;
use cmp;
+use cmp::{PartialEq, PartialOrd, Ord};
+use mem;
use num::{Zero, One, CheckedAdd, CheckedSub, Saturating, ToPrimitive, Int};
-use option::{Option, Some, None};
use ops::{Add, Mul, Sub};
-use cmp::{PartialEq, PartialOrd, Ord};
-use clone::Clone;
+use option::{Option, Some, None};
use uint;
-use mem;
/// Conversion from an `Iterator`
pub trait FromIterator<A> {
///
/// # Example
///
- /// ```rust
+ /// ```rust,ignore
/// range(0u, 5).advance(|x| {print!("{} ", x); true});
/// ```
+ #[deprecated = "use the `all` method instead"]
#[inline]
fn advance(&mut self, f: |A| -> bool) -> bool {
loop {
/// An double-ended iterator with the direction inverted
#[deriving(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Rev<T> {
iter: T
}
}
/// A mutable reference to an iterator
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct ByRef<'a, T> {
iter: &'a mut T
}
/// An iterator that repeats endlessly
#[deriving(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Cycle<T> {
orig: T,
iter: T,
/// An iterator which strings two iterators together
#[deriving(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Chain<T, U> {
a: T,
b: U,
/// An iterator which iterates two other iterators simultaneously
#[deriving(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Zip<T, U> {
a: T,
b: U
}
/// An iterator which maps the values of `iter` with `f`
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Map<'a, A, B, T> {
iter: T,
f: |A|: 'a -> B
}
/// An iterator which filters the elements of `iter` with `predicate`
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Filter<'a, A, T> {
iter: T,
predicate: |&A|: 'a -> bool
}
/// An iterator which uses `f` to both filter and map elements from `iter`
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct FilterMap<'a, A, B, T> {
iter: T,
f: |A|: 'a -> Option<B>
/// An iterator which yields the current count and the element during iteration
#[deriving(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Enumerate<T> {
iter: T,
count: uint
}
/// An iterator with a `peek()` that returns an optional reference to the next element.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Peekable<A, T> {
iter: T,
peeked: Option<A>,
}
/// An iterator which rejects elements while `predicate` is true
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct SkipWhile<'a, A, T> {
iter: T,
flag: bool,
}
/// An iterator which only accepts elements while `predicate` is true
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct TakeWhile<'a, A, T> {
iter: T,
flag: bool,
/// An iterator which skips over `n` elements of `iter`.
#[deriving(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Skip<T> {
iter: T,
n: uint
/// An iterator which only iterates over the first `n` iterations of `iter`.
#[deriving(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Take<T> {
iter: T,
n: uint
/// An iterator to maintain state while iterating another iterator
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Scan<'a, A, B, T, St> {
iter: T,
f: |&mut St, A|: 'a -> Option<B>,
/// An iterator that maps each element to an iterator,
/// and yields the elements of the produced iterators
///
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct FlatMap<'a, A, T, U> {
iter: T,
f: |A|: 'a -> U,
/// An iterator that yields `None` forever after the underlying iterator
/// yields `None` once.
#[deriving(Clone)]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Fuse<T> {
iter: T,
done: bool
/// An iterator that calls a function with a reference to each
/// element before yielding it.
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Inspect<'a, A, T> {
iter: T,
f: |&A|: 'a
fn idx(&mut self, _: uint) -> Option<A> { Some(self.element.clone()) }
}
+type IterateState<'a, T> = (|T|: 'a -> T, Option<T>, bool);
+
+/// An iterator that repeatedly applies a given function, starting
+/// from a given seed value.
+pub type Iterate<'a, T> = Unfold<'a, T, IterateState<'a, T>>;
+
+/// Creates a new iterator that produces an infinite sequence of
+/// repeated applications of the given function `f`.
+#[allow(visible_private_types)]
+pub fn iterate<'a, T: Clone>(f: |T|: 'a -> T, seed: T) -> Iterate<'a, T> {
+ Unfold::new((f, Some(seed), true), |st| {
+ let &(ref mut f, ref mut val, ref mut first) = st;
+ if *first {
+ *first = false;
+ } else {
+ val.mutate(|x| (*f)(x));
+ }
+ val.clone()
+ })
+}
+
/// Functions for lexicographical ordering of sequences.
///
/// Lexicographical ordering through `<`, `<=`, `>=`, `>` requires
}
}
}
-
// Since libcore defines many fundamental lang items, all tests live in a
// separate crate, libcoretest, to avoid bizarre issues.
-#![crate_id = "core#0.11.0"]
+#![crate_name = "core"]
#![experimental]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
#![no_std]
/* Core types and methods on primitives */
-mod unicode;
pub mod any;
pub mod atomics;
pub mod bool;
//! Operations and constants for 32-bits floats (`f32` type)
#![doc(primitive = "f32")]
+// FIXME: MIN_VALUE and MAX_VALUE literals are parsed as -inf and inf #14353
+#![allow(type_overflow)]
use intrinsics;
use mem;
//! Operations and constants for 64-bits floats (`f64` type)
#![doc(primitive = "f64")]
+// FIXME: MIN_VALUE and MAX_VALUE literals are parsed as -inf and inf #14353
+#![allow(type_overflow)]
use intrinsics;
use mem;
}
macro_rules! impl_to_primitive_int_to_int(
- ($SrcT:ty, $DstT:ty) => (
+ ($SrcT:ty, $DstT:ty, $slf:expr) => (
{
if size_of::<$SrcT>() <= size_of::<$DstT>() {
- Some(*self as $DstT)
+ Some($slf as $DstT)
} else {
- let n = *self as i64;
+ let n = $slf as i64;
let min_value: $DstT = Bounded::min_value();
let max_value: $DstT = Bounded::max_value();
if min_value as i64 <= n && n <= max_value as i64 {
- Some(*self as $DstT)
+ Some($slf as $DstT)
} else {
None
}
)
macro_rules! impl_to_primitive_int_to_uint(
- ($SrcT:ty, $DstT:ty) => (
+ ($SrcT:ty, $DstT:ty, $slf:expr) => (
{
let zero: $SrcT = Zero::zero();
let max_value: $DstT = Bounded::max_value();
- if zero <= *self && *self as u64 <= max_value as u64 {
- Some(*self as $DstT)
+ if zero <= $slf && $slf as u64 <= max_value as u64 {
+ Some($slf as $DstT)
} else {
None
}
($T:ty) => (
impl ToPrimitive for $T {
#[inline]
- fn to_int(&self) -> Option<int> { impl_to_primitive_int_to_int!($T, int) }
+ fn to_int(&self) -> Option<int> { impl_to_primitive_int_to_int!($T, int, *self) }
#[inline]
- fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8) }
+ fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8, *self) }
#[inline]
- fn to_i16(&self) -> Option<i16> { impl_to_primitive_int_to_int!($T, i16) }
+ fn to_i16(&self) -> Option<i16> { impl_to_primitive_int_to_int!($T, i16, *self) }
#[inline]
- fn to_i32(&self) -> Option<i32> { impl_to_primitive_int_to_int!($T, i32) }
+ fn to_i32(&self) -> Option<i32> { impl_to_primitive_int_to_int!($T, i32, *self) }
#[inline]
- fn to_i64(&self) -> Option<i64> { impl_to_primitive_int_to_int!($T, i64) }
+ fn to_i64(&self) -> Option<i64> { impl_to_primitive_int_to_int!($T, i64, *self) }
#[inline]
- fn to_uint(&self) -> Option<uint> { impl_to_primitive_int_to_uint!($T, uint) }
+ fn to_uint(&self) -> Option<uint> { impl_to_primitive_int_to_uint!($T, uint, *self) }
#[inline]
- fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8) }
+ fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8, *self) }
#[inline]
- fn to_u16(&self) -> Option<u16> { impl_to_primitive_int_to_uint!($T, u16) }
+ fn to_u16(&self) -> Option<u16> { impl_to_primitive_int_to_uint!($T, u16, *self) }
#[inline]
- fn to_u32(&self) -> Option<u32> { impl_to_primitive_int_to_uint!($T, u32) }
+ fn to_u32(&self) -> Option<u32> { impl_to_primitive_int_to_uint!($T, u32, *self) }
#[inline]
- fn to_u64(&self) -> Option<u64> { impl_to_primitive_int_to_uint!($T, u64) }
+ fn to_u64(&self) -> Option<u64> { impl_to_primitive_int_to_uint!($T, u64, *self) }
#[inline]
fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
impl_to_primitive_int!(i64)
macro_rules! impl_to_primitive_uint_to_int(
- ($DstT:ty) => (
+ ($DstT:ty, $slf:expr) => (
{
let max_value: $DstT = Bounded::max_value();
- if *self as u64 <= max_value as u64 {
- Some(*self as $DstT)
+ if $slf as u64 <= max_value as u64 {
+ Some($slf as $DstT)
} else {
None
}
)
macro_rules! impl_to_primitive_uint_to_uint(
- ($SrcT:ty, $DstT:ty) => (
+ ($SrcT:ty, $DstT:ty, $slf:expr) => (
{
if size_of::<$SrcT>() <= size_of::<$DstT>() {
- Some(*self as $DstT)
+ Some($slf as $DstT)
} else {
let zero: $SrcT = Zero::zero();
let max_value: $DstT = Bounded::max_value();
- if zero <= *self && *self as u64 <= max_value as u64 {
- Some(*self as $DstT)
+ if zero <= $slf && $slf as u64 <= max_value as u64 {
+ Some($slf as $DstT)
} else {
None
}
($T:ty) => (
impl ToPrimitive for $T {
#[inline]
- fn to_int(&self) -> Option<int> { impl_to_primitive_uint_to_int!(int) }
+ fn to_int(&self) -> Option<int> { impl_to_primitive_uint_to_int!(int, *self) }
#[inline]
- fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8) }
+ fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8, *self) }
#[inline]
- fn to_i16(&self) -> Option<i16> { impl_to_primitive_uint_to_int!(i16) }
+ fn to_i16(&self) -> Option<i16> { impl_to_primitive_uint_to_int!(i16, *self) }
#[inline]
- fn to_i32(&self) -> Option<i32> { impl_to_primitive_uint_to_int!(i32) }
+ fn to_i32(&self) -> Option<i32> { impl_to_primitive_uint_to_int!(i32, *self) }
#[inline]
- fn to_i64(&self) -> Option<i64> { impl_to_primitive_uint_to_int!(i64) }
+ fn to_i64(&self) -> Option<i64> { impl_to_primitive_uint_to_int!(i64, *self) }
#[inline]
- fn to_uint(&self) -> Option<uint> { impl_to_primitive_uint_to_uint!($T, uint) }
+ fn to_uint(&self) -> Option<uint> { impl_to_primitive_uint_to_uint!($T, uint, *self) }
#[inline]
- fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8) }
+ fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8, *self) }
#[inline]
- fn to_u16(&self) -> Option<u16> { impl_to_primitive_uint_to_uint!($T, u16) }
+ fn to_u16(&self) -> Option<u16> { impl_to_primitive_uint_to_uint!($T, u16, *self) }
#[inline]
- fn to_u32(&self) -> Option<u32> { impl_to_primitive_uint_to_uint!($T, u32) }
+ fn to_u32(&self) -> Option<u32> { impl_to_primitive_uint_to_uint!($T, u32, *self) }
#[inline]
- fn to_u64(&self) -> Option<u64> { impl_to_primitive_uint_to_uint!($T, u64) }
+ fn to_u64(&self) -> Option<u64> { impl_to_primitive_uint_to_uint!($T, u64, *self) }
#[inline]
fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
impl_to_primitive_uint!(u64)
macro_rules! impl_to_primitive_float_to_float(
- ($SrcT:ty, $DstT:ty) => (
+ ($SrcT:ty, $DstT:ty, $slf:expr) => (
if size_of::<$SrcT>() <= size_of::<$DstT>() {
- Some(*self as $DstT)
+ Some($slf as $DstT)
} else {
- let n = *self as f64;
+ let n = $slf as f64;
let max_value: $SrcT = Bounded::max_value();
if -max_value as f64 <= n && n <= max_value as f64 {
- Some(*self as $DstT)
+ Some($slf as $DstT)
} else {
None
}
fn to_u64(&self) -> Option<u64> { Some(*self as u64) }
#[inline]
- fn to_f32(&self) -> Option<f32> { impl_to_primitive_float_to_float!($T, f32) }
+ fn to_f32(&self) -> Option<f32> { impl_to_primitive_float_to_float!($T, f32, *self) }
#[inline]
- fn to_f64(&self) -> Option<f64> { impl_to_primitive_float_to_float!($T, f64) }
+ fn to_f64(&self) -> Option<f64> { impl_to_primitive_float_to_float!($T, f64, *self) }
}
)
)
}
macro_rules! impl_from_primitive(
- ($T:ty, $to_ty:expr) => (
+ ($T:ty, $to_ty:ident) => (
impl FromPrimitive for $T {
- #[inline] fn from_int(n: int) -> Option<$T> { $to_ty }
- #[inline] fn from_i8(n: i8) -> Option<$T> { $to_ty }
- #[inline] fn from_i16(n: i16) -> Option<$T> { $to_ty }
- #[inline] fn from_i32(n: i32) -> Option<$T> { $to_ty }
- #[inline] fn from_i64(n: i64) -> Option<$T> { $to_ty }
-
- #[inline] fn from_uint(n: uint) -> Option<$T> { $to_ty }
- #[inline] fn from_u8(n: u8) -> Option<$T> { $to_ty }
- #[inline] fn from_u16(n: u16) -> Option<$T> { $to_ty }
- #[inline] fn from_u32(n: u32) -> Option<$T> { $to_ty }
- #[inline] fn from_u64(n: u64) -> Option<$T> { $to_ty }
-
- #[inline] fn from_f32(n: f32) -> Option<$T> { $to_ty }
- #[inline] fn from_f64(n: f64) -> Option<$T> { $to_ty }
+ #[inline] fn from_int(n: int) -> Option<$T> { n.$to_ty() }
+ #[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() }
+ #[inline] fn from_i16(n: i16) -> Option<$T> { n.$to_ty() }
+ #[inline] fn from_i32(n: i32) -> Option<$T> { n.$to_ty() }
+ #[inline] fn from_i64(n: i64) -> Option<$T> { n.$to_ty() }
+
+ #[inline] fn from_uint(n: uint) -> Option<$T> { n.$to_ty() }
+ #[inline] fn from_u8(n: u8) -> Option<$T> { n.$to_ty() }
+ #[inline] fn from_u16(n: u16) -> Option<$T> { n.$to_ty() }
+ #[inline] fn from_u32(n: u32) -> Option<$T> { n.$to_ty() }
+ #[inline] fn from_u64(n: u64) -> Option<$T> { n.$to_ty() }
+
+ #[inline] fn from_f32(n: f32) -> Option<$T> { n.$to_ty() }
+ #[inline] fn from_f64(n: f64) -> Option<$T> { n.$to_ty() }
}
)
)
-impl_from_primitive!(int, n.to_int())
-impl_from_primitive!(i8, n.to_i8())
-impl_from_primitive!(i16, n.to_i16())
-impl_from_primitive!(i32, n.to_i32())
-impl_from_primitive!(i64, n.to_i64())
-impl_from_primitive!(uint, n.to_uint())
-impl_from_primitive!(u8, n.to_u8())
-impl_from_primitive!(u16, n.to_u16())
-impl_from_primitive!(u32, n.to_u32())
-impl_from_primitive!(u64, n.to_u64())
-impl_from_primitive!(f32, n.to_f32())
-impl_from_primitive!(f64, n.to_f64())
+impl_from_primitive!(int, to_int)
+impl_from_primitive!(i8, to_i8)
+impl_from_primitive!(i16, to_i16)
+impl_from_primitive!(i32, to_i32)
+impl_from_primitive!(i64, to_i64)
+impl_from_primitive!(uint, to_uint)
+impl_from_primitive!(u8, to_u8)
+impl_from_primitive!(u16, to_u16)
+impl_from_primitive!(u32, to_u32)
+impl_from_primitive!(u64, to_u64)
+impl_from_primitive!(f32, to_f32)
+impl_from_primitive!(f64, to_f64)
/// Cast from one machine scalar to another.
///
/**
*
* The `Index` trait is used to specify the functionality of indexing operations
- * like `arr[idx]`.
+ * like `arr[idx]` when used in an immutable context.
*
* # Example
*
* struct Foo;
*
* impl Index<Foo, Foo> for Foo {
- * fn index(&self, _rhs: &Foo) -> Foo {
+ * fn index<'a>(&'a self, _rhs: &Foo) -> &'a Foo {
* println!("Indexing!");
- * *self
+ * self
* }
* }
*
#[lang="index"]
pub trait Index<Index,Result> {
/// The method for the indexing (`Foo[Bar]`) operation
- fn index(&self, index: &Index) -> Result;
+ fn index<'a>(&'a self, index: &Index) -> &'a Result;
+}
+
+/**
+ *
+ * The `IndexMut` trait is used to specify the functionality of indexing
+ * operations like `arr[idx]`, when used in a mutable context.
+ *
+ * # Example
+ *
+ * A trivial implementation of `IndexMut`. When `Foo[Foo]` happens, it ends up
+ * calling `index`, and therefore, `main` prints `Indexing!`.
+ *
+ * ```
+ * struct Foo;
+ *
+ * impl IndexMut<Foo, Foo> for Foo {
+ * fn index_mut<'a>(&'a mut self, _rhs: &Foo) -> &'a mut Foo {
+ * println!("Indexing!");
+ * self
+ * }
+ * }
+ *
+ * fn main() {
+ * &mut Foo[Foo];
+ * }
+ * ```
+ */
+#[lang="index_mut"]
+pub trait IndexMut<Index,Result> {
+ /// The method for the indexing (`Foo[Bar]`) operation
+ fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Result;
}
/**
pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
pub use ops::{BitAnd, BitOr, BitXor};
pub use ops::{Drop, Deref, DerefMut};
-pub use ops::{Shl, Shr, Index};
+pub use ops::{Shl, Shr};
+pub use ops::{Index, IndexMut};
pub use option::{Option, Some, None};
pub use result::{Result, Ok, Err};
use cmp::{PartialEq, Eq, PartialOrd, Equiv, Ordering, Less, Equal, Greater};
+pub use intrinsics::copy_memory;
+pub use intrinsics::copy_nonoverlapping_memory;
+pub use intrinsics::set_memory;
+
/// Create a null pointer.
///
/// # Example
#[unstable = "may need a different name after pending changes to pointer types"]
pub fn mut_null<T>() -> *mut T { 0 as *mut T }
-/// Copies data from one location to another.
-///
-/// Copies `count` elements (not bytes) from `src` to `dst`. The source
-/// and destination may overlap.
-///
-/// `copy_memory` is semantically equivalent to C's `memmove`.
-///
-/// # Example
-///
-/// Efficiently create a Rust vector from an unsafe buffer:
-///
-/// ```
-/// use std::ptr;
-///
-/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: uint) -> Vec<T> {
-/// let mut dst = Vec::with_capacity(elts);
-/// dst.set_len(elts);
-/// ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
-/// dst
-/// }
-/// ```
-///
-#[inline]
-#[unstable]
-pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
- intrinsics::copy_memory(dst, src, count)
-}
-
-/// Copies data from one location to another.
-///
-/// Copies `count` elements (not bytes) from `src` to `dst`. The source
-/// and destination may *not* overlap.
-///
-/// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
-///
-/// # Example
-///
-/// A safe swap function:
-///
-/// ```
-/// use std::mem;
-/// use std::ptr;
-///
-/// fn swap<T>(x: &mut T, y: &mut T) {
-/// unsafe {
-/// // Give ourselves some scratch space to work with
-/// let mut t: T = mem::uninitialized();
-///
-/// // Perform the swap, `&mut` pointers never alias
-/// ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
-/// ptr::copy_nonoverlapping_memory(x, &*y, 1);
-/// ptr::copy_nonoverlapping_memory(y, &t, 1);
-///
-/// // y and t now point to the same thing, but we need to completely forget `tmp`
-/// // because it's no longer relevant.
-/// mem::forget(t);
-/// }
-/// }
-/// ```
-///
-/// # Safety Note
-///
-/// If the source and destination overlap then the behavior of this
-/// function is undefined.
-#[inline]
-#[unstable]
-pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
- src: *const T,
- count: uint) {
- intrinsics::copy_nonoverlapping_memory(dst, src, count)
-}
-
-/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
-/// bytes of memory starting at `dst` to `c`.
-#[inline]
-#[experimental = "uncertain about naming and semantics"]
-pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
- intrinsics::set_memory(dst, c, count)
-}
-
/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
#[inline]
#[experimental = "uncertain about naming and semantics"]
//! Error handling with the `Result` type
//!
-//! `Result<T>` is the type used for returning and propagating
+//! `Result<T, E>` is the type used for returning and propagating
//! errors. It is an enum with the variants, `Ok(T)`, representing
//! success and containing a value, and `Err(E)`, representing error
//! and containing an error value.
impl<T, E: Show> Result<T, E> {
/// Unwraps a result, yielding the content of an `Ok`.
///
- /// Fails if the value is an `Err`.
+ /// # Failure
+ ///
+ /// Fails if the value is an `Err`, with a custom failure message provided
+ /// by the `Err`'s value.
#[inline]
pub fn unwrap(self) -> T {
match self {
impl<T: Show, E> Result<T, E> {
/// Unwraps a result, yielding the content of an `Err`.
///
- /// Fails if the value is an `Ok`.
+ /// # Failure
+ ///
+ /// Fails if the value is an `Ok`, with a custom failure message provided
+ /// by the `Ok`'s value.
#[inline]
pub fn unwrap_err(self) -> E {
match self {
if self.ptr == self.end {
None
} else {
- let old = self.ptr;
- self.ptr = if mem::size_of::<T>() == 0 {
+ if mem::size_of::<T>() == 0 {
// purposefully don't use 'ptr.offset' because for
// vectors with 0-size elements this would return the
// same pointer.
- transmute(self.ptr as uint + 1)
+ self.ptr = transmute(self.ptr as uint + 1);
+
+ // Use a non-null pointer value
+ Some(transmute(1u))
} else {
- self.ptr.offset(1)
- };
+ let old = self.ptr;
+ self.ptr = self.ptr.offset(1);
- Some(transmute(old))
+ Some(transmute(old))
+ }
}
}
}
if self.end == self.ptr {
None
} else {
- self.end = if mem::size_of::<T>() == 0 {
+ if mem::size_of::<T>() == 0 {
// See above for why 'ptr.offset' isn't used
- transmute(self.end as uint - 1)
+ self.end = transmute(self.end as uint - 1);
+
+ // Use a non-null pointer value
+ Some(transmute(1u))
} else {
- self.end.offset(-1)
- };
- Some(transmute(self.end))
+ self.end = self.end.offset(-1);
+
+ Some(transmute(self.end))
+ }
}
}
}
fn idx(&mut self, index: uint) -> Option<&'a T> {
unsafe {
if index < self.indexable() {
- transmute(self.ptr.offset(index as int))
+ if mem::size_of::<T>() == 0 {
+ // Use a non-null pointer value
+ Some(transmute(1u))
+ } else {
+ Some(transmute(self.ptr.offset(index as int)))
+ }
} else {
None
}
use cmp::{PartialEq, Eq};
use collections::Collection;
use default::Default;
-use iter::{Filter, Map, Iterator};
+use iter::{Map, Iterator};
use iter::{DoubleEndedIterator, ExactSize};
use iter::range;
use num::{CheckedMul, Saturating};
invert: bool,
}
-/// An iterator over the words of a string, separated by a sequence of whitespace
-pub type Words<'a> =
- Filter<'a, &'a str, CharSplits<'a, extern "Rust" fn(char) -> bool>>;
-
/// An iterator over the lines of a string, separated by either `\n` or (`\r\n`).
pub type AnyLines<'a> =
Map<'a, &'a str, &'a str, CharSplits<'a, char>>;
/// ```
fn lines_any(&self) -> AnyLines<'a>;
- /// An iterator over the words of a string (subsequences separated
- /// by any sequence of whitespace). Sequences of whitespace are
- /// collapsed, so empty "words" are not included.
- ///
- /// # Example
- ///
- /// ```rust
- /// let some_words = " Mary had\ta little \n\t lamb";
- /// let v: Vec<&str> = some_words.words().collect();
- /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
- /// ```
- fn words(&self) -> Words<'a>;
-
- /// Returns true if the string contains only whitespace.
- ///
- /// Whitespace characters are determined by `char::is_whitespace`.
- ///
- /// # Example
- ///
- /// ```rust
- /// assert!(" \t\n".is_whitespace());
- /// assert!("".is_whitespace());
- ///
- /// assert!( !"abc".is_whitespace());
- /// ```
- fn is_whitespace(&self) -> bool;
-
- /// Returns true if the string contains only alphanumeric code
- /// points.
- ///
- /// Alphanumeric characters are determined by `char::is_alphanumeric`.
- ///
- /// # Example
- ///
- /// ```rust
- /// assert!("Löwe老虎Léopard123".is_alphanumeric());
- /// assert!("".is_alphanumeric());
- ///
- /// assert!( !" &*~".is_alphanumeric());
- /// ```
- fn is_alphanumeric(&self) -> bool;
-
/// Returns the number of Unicode code points (`char`) that a
/// string holds.
///
/// Returns true if `needle` is a suffix of the string.
fn ends_with(&self, needle: &str) -> bool;
- /// Returns a string with leading and trailing whitespace removed.
- fn trim(&self) -> &'a str;
-
- /// Returns a string with leading whitespace removed.
- fn trim_left(&self) -> &'a str;
-
- /// Returns a string with trailing whitespace removed.
- fn trim_right(&self) -> &'a str;
-
/// Returns a string with characters that match `to_trim` removed.
///
/// # Arguments
})
}
- #[inline]
- fn words(&self) -> Words<'a> {
- self.split(char::is_whitespace).filter(|s| !s.is_empty())
- }
-
- #[inline]
- fn is_whitespace(&self) -> bool { self.chars().all(char::is_whitespace) }
-
- #[inline]
- fn is_alphanumeric(&self) -> bool { self.chars().all(char::is_alphanumeric) }
-
#[inline]
fn char_len(&self) -> uint { self.chars().count() }
#[inline]
fn slice(&self, begin: uint, end: uint) -> &'a str {
- assert!(self.is_char_boundary(begin) && self.is_char_boundary(end));
+ assert!(self.is_char_boundary(begin) && self.is_char_boundary(end),
+ "index {} and/or {} in `{}` do not lie on character boundary", begin,
+ end, *self);
unsafe { raw::slice_bytes(*self, begin, end) }
}
#[inline]
fn slice_to(&self, end: uint) -> &'a str {
- assert!(self.is_char_boundary(end));
+ assert!(self.is_char_boundary(end), "index {} in `{}` does not lie on \
+ a character boundary", end, *self);
unsafe { raw::slice_bytes(*self, 0, end) }
}
m >= n && needle.as_bytes() == self.as_bytes().slice_from(m - n)
}
- #[inline]
- fn trim(&self) -> &'a str {
- self.trim_left().trim_right()
- }
-
- #[inline]
- fn trim_left(&self) -> &'a str {
- self.trim_left_chars(char::is_whitespace)
- }
-
- #[inline]
- fn trim_right(&self) -> &'a str {
- self.trim_right_chars(char::is_whitespace)
- }
-
#[inline]
fn trim_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str {
let cur = match self.find(|c: char| !to_trim.matches(c)) {
+++ /dev/null
-// Copyright 2012-2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly
-
-#![allow(missing_doc, non_uppercase_statics, non_snake_case_functions)]
-
-
-fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
- use cmp::{Equal, Less, Greater};
- use slice::ImmutableVector;
- use option::None;
- r.bsearch(|&(lo,hi)| {
- if lo <= c && c <= hi { Equal }
- else if hi < c { Less }
- else { Greater }
- }) != None
-}
-
-pub mod general_category {
- static Cc_table : &'static [(char,char)] = &[
- ('\x00', '\x1f'), ('\x7f', '\x9f')
- ];
-
- pub fn Cc(c: char) -> bool {
- super::bsearch_range_table(c, Cc_table)
- }
-
- static Nd_table : &'static [(char,char)] = &[
- ('\x30', '\x39'), ('\u0660', '\u0669'),
- ('\u06f0', '\u06f9'), ('\u07c0', '\u07c9'),
- ('\u0966', '\u096f'), ('\u09e6', '\u09ef'),
- ('\u0a66', '\u0a6f'), ('\u0ae6', '\u0aef'),
- ('\u0b66', '\u0b6f'), ('\u0be6', '\u0bef'),
- ('\u0c66', '\u0c6f'), ('\u0ce6', '\u0cef'),
- ('\u0d66', '\u0d6f'), ('\u0e50', '\u0e59'),
- ('\u0ed0', '\u0ed9'), ('\u0f20', '\u0f29'),
- ('\u1040', '\u1049'), ('\u1090', '\u1099'),
- ('\u17e0', '\u17e9'), ('\u1810', '\u1819'),
- ('\u1946', '\u194f'), ('\u19d0', '\u19d9'),
- ('\u1a80', '\u1a99'), ('\u1b50', '\u1b59'),
- ('\u1bb0', '\u1bb9'), ('\u1c40', '\u1c49'),
- ('\u1c50', '\u1c59'), ('\ua620', '\ua629'),
- ('\ua8d0', '\ua8d9'), ('\ua900', '\ua909'),
- ('\ua9d0', '\ua9d9'), ('\uaa50', '\uaa59'),
- ('\uabf0', '\uabf9'), ('\uff10', '\uff19'),
- ('\U000104a0', '\U000104a9'), ('\U00011066', '\U0001106f'),
- ('\U000110f0', '\U000110f9'), ('\U00011136', '\U0001113f'),
- ('\U000111d0', '\U000111d9'), ('\U000116c0', '\U000116c9'),
- ('\U0001d7ce', '\U0001d7ff')
- ];
-
- pub fn Nd(c: char) -> bool {
- super::bsearch_range_table(c, Nd_table)
- }
-
- static Nl_table : &'static [(char,char)] = &[
- ('\u16ee', '\u16f0'), ('\u2160', '\u2182'),
- ('\u2185', '\u2188'), ('\u3007', '\u3007'),
- ('\u3021', '\u3029'), ('\u3038', '\u303a'),
- ('\ua6e6', '\ua6ef'), ('\U00010140', '\U00010174'),
- ('\U00010341', '\U00010341'), ('\U0001034a', '\U0001034a'),
- ('\U000103d1', '\U000103d5'), ('\U00012400', '\U00012462')
- ];
-
- pub fn Nl(c: char) -> bool {
- super::bsearch_range_table(c, Nl_table)
- }
-
- static No_table : &'static [(char,char)] = &[
- ('\xb2', '\xb3'), ('\xb9', '\xb9'),
- ('\xbc', '\xbe'), ('\u09f4', '\u09f9'),
- ('\u0b72', '\u0b77'), ('\u0bf0', '\u0bf2'),
- ('\u0c78', '\u0c7e'), ('\u0d70', '\u0d75'),
- ('\u0f2a', '\u0f33'), ('\u1369', '\u137c'),
- ('\u17f0', '\u17f9'), ('\u19da', '\u19da'),
- ('\u2070', '\u2070'), ('\u2074', '\u2079'),
- ('\u2080', '\u2089'), ('\u2150', '\u215f'),
- ('\u2189', '\u2189'), ('\u2460', '\u249b'),
- ('\u24ea', '\u24ff'), ('\u2776', '\u2793'),
- ('\u2cfd', '\u2cfd'), ('\u3192', '\u3195'),
- ('\u3220', '\u3229'), ('\u3248', '\u324f'),
- ('\u3251', '\u325f'), ('\u3280', '\u3289'),
- ('\u32b1', '\u32bf'), ('\ua830', '\ua835'),
- ('\U00010107', '\U00010133'), ('\U00010175', '\U00010178'),
- ('\U0001018a', '\U0001018a'), ('\U00010320', '\U00010323'),
- ('\U00010858', '\U0001085f'), ('\U00010916', '\U0001091b'),
- ('\U00010a40', '\U00010a47'), ('\U00010a7d', '\U00010a7e'),
- ('\U00010b58', '\U00010b5f'), ('\U00010b78', '\U00010b7f'),
- ('\U00010e60', '\U00010e7e'), ('\U00011052', '\U00011065'),
- ('\U0001d360', '\U0001d371'), ('\U0001f100', '\U0001f10a')
- ];
-
- pub fn No(c: char) -> bool {
- super::bsearch_range_table(c, No_table)
- }
-
-}
-
-pub mod normalization {
- use option::Option;
- use option::{Some, None};
- use slice::ImmutableVector;
-
- fn bsearch_table(c: char, r: &'static [(char, &'static [char])]) -> Option<&'static [char]> {
- use cmp::{Equal, Less, Greater};
- match r.bsearch(|&(val, _)| {
- if c == val { Equal }
- else if val < c { Less }
- else { Greater }
- }) {
- Some(idx) => {
- let (_, result) = r[idx];
- Some(result)
- }
- None => None
- }
- }
-
-
- // Canonical decompositions
- static canonical_table : &'static [(char, &'static [char])] = &[
- ('\xc0', &['\x41', '\u0300']), ('\xc1', &['\x41', '\u0301']), ('\xc2', &['\x41', '\u0302']),
- ('\xc3', &['\x41', '\u0303']), ('\xc4', &['\x41', '\u0308']), ('\xc5', &['\x41', '\u030a']),
- ('\xc7', &['\x43', '\u0327']), ('\xc8', &['\x45', '\u0300']), ('\xc9', &['\x45', '\u0301']),
- ('\xca', &['\x45', '\u0302']), ('\xcb', &['\x45', '\u0308']), ('\xcc', &['\x49', '\u0300']),
- ('\xcd', &['\x49', '\u0301']), ('\xce', &['\x49', '\u0302']), ('\xcf', &['\x49', '\u0308']),
- ('\xd1', &['\x4e', '\u0303']), ('\xd2', &['\x4f', '\u0300']), ('\xd3', &['\x4f', '\u0301']),
- ('\xd4', &['\x4f', '\u0302']), ('\xd5', &['\x4f', '\u0303']), ('\xd6', &['\x4f', '\u0308']),
- ('\xd9', &['\x55', '\u0300']), ('\xda', &['\x55', '\u0301']), ('\xdb', &['\x55', '\u0302']),
- ('\xdc', &['\x55', '\u0308']), ('\xdd', &['\x59', '\u0301']), ('\xe0', &['\x61', '\u0300']),
- ('\xe1', &['\x61', '\u0301']), ('\xe2', &['\x61', '\u0302']), ('\xe3', &['\x61', '\u0303']),
- ('\xe4', &['\x61', '\u0308']), ('\xe5', &['\x61', '\u030a']), ('\xe7', &['\x63', '\u0327']),
- ('\xe8', &['\x65', '\u0300']), ('\xe9', &['\x65', '\u0301']), ('\xea', &['\x65', '\u0302']),
- ('\xeb', &['\x65', '\u0308']), ('\xec', &['\x69', '\u0300']), ('\xed', &['\x69', '\u0301']),
- ('\xee', &['\x69', '\u0302']), ('\xef', &['\x69', '\u0308']), ('\xf1', &['\x6e', '\u0303']),
- ('\xf2', &['\x6f', '\u0300']), ('\xf3', &['\x6f', '\u0301']), ('\xf4', &['\x6f', '\u0302']),
- ('\xf5', &['\x6f', '\u0303']), ('\xf6', &['\x6f', '\u0308']), ('\xf9', &['\x75', '\u0300']),
- ('\xfa', &['\x75', '\u0301']), ('\xfb', &['\x75', '\u0302']), ('\xfc', &['\x75', '\u0308']),
- ('\xfd', &['\x79', '\u0301']), ('\xff', &['\x79', '\u0308']), ('\u0100', &['\x41',
- '\u0304']), ('\u0101', &['\x61', '\u0304']), ('\u0102', &['\x41', '\u0306']), ('\u0103',
- &['\x61', '\u0306']), ('\u0104', &['\x41', '\u0328']), ('\u0105', &['\x61', '\u0328']),
- ('\u0106', &['\x43', '\u0301']), ('\u0107', &['\x63', '\u0301']), ('\u0108', &['\x43',
- '\u0302']), ('\u0109', &['\x63', '\u0302']), ('\u010a', &['\x43', '\u0307']), ('\u010b',
- &['\x63', '\u0307']), ('\u010c', &['\x43', '\u030c']), ('\u010d', &['\x63', '\u030c']),
- ('\u010e', &['\x44', '\u030c']), ('\u010f', &['\x64', '\u030c']), ('\u0112', &['\x45',
- '\u0304']), ('\u0113', &['\x65', '\u0304']), ('\u0114', &['\x45', '\u0306']), ('\u0115',
- &['\x65', '\u0306']), ('\u0116', &['\x45', '\u0307']), ('\u0117', &['\x65', '\u0307']),
- ('\u0118', &['\x45', '\u0328']), ('\u0119', &['\x65', '\u0328']), ('\u011a', &['\x45',
- '\u030c']), ('\u011b', &['\x65', '\u030c']), ('\u011c', &['\x47', '\u0302']), ('\u011d',
- &['\x67', '\u0302']), ('\u011e', &['\x47', '\u0306']), ('\u011f', &['\x67', '\u0306']),
- ('\u0120', &['\x47', '\u0307']), ('\u0121', &['\x67', '\u0307']), ('\u0122', &['\x47',
- '\u0327']), ('\u0123', &['\x67', '\u0327']), ('\u0124', &['\x48', '\u0302']), ('\u0125',
- &['\x68', '\u0302']), ('\u0128', &['\x49', '\u0303']), ('\u0129', &['\x69', '\u0303']),
- ('\u012a', &['\x49', '\u0304']), ('\u012b', &['\x69', '\u0304']), ('\u012c', &['\x49',
- '\u0306']), ('\u012d', &['\x69', '\u0306']), ('\u012e', &['\x49', '\u0328']), ('\u012f',
- &['\x69', '\u0328']), ('\u0130', &['\x49', '\u0307']), ('\u0134', &['\x4a', '\u0302']),
- ('\u0135', &['\x6a', '\u0302']), ('\u0136', &['\x4b', '\u0327']), ('\u0137', &['\x6b',
- '\u0327']), ('\u0139', &['\x4c', '\u0301']), ('\u013a', &['\x6c', '\u0301']), ('\u013b',
- &['\x4c', '\u0327']), ('\u013c', &['\x6c', '\u0327']), ('\u013d', &['\x4c', '\u030c']),
- ('\u013e', &['\x6c', '\u030c']), ('\u0143', &['\x4e', '\u0301']), ('\u0144', &['\x6e',
- '\u0301']), ('\u0145', &['\x4e', '\u0327']), ('\u0146', &['\x6e', '\u0327']), ('\u0147',
- &['\x4e', '\u030c']), ('\u0148', &['\x6e', '\u030c']), ('\u014c', &['\x4f', '\u0304']),
- ('\u014d', &['\x6f', '\u0304']), ('\u014e', &['\x4f', '\u0306']), ('\u014f', &['\x6f',
- '\u0306']), ('\u0150', &['\x4f', '\u030b']), ('\u0151', &['\x6f', '\u030b']), ('\u0154',
- &['\x52', '\u0301']), ('\u0155', &['\x72', '\u0301']), ('\u0156', &['\x52', '\u0327']),
- ('\u0157', &['\x72', '\u0327']), ('\u0158', &['\x52', '\u030c']), ('\u0159', &['\x72',
- '\u030c']), ('\u015a', &['\x53', '\u0301']), ('\u015b', &['\x73', '\u0301']), ('\u015c',
- &['\x53', '\u0302']), ('\u015d', &['\x73', '\u0302']), ('\u015e', &['\x53', '\u0327']),
- ('\u015f', &['\x73', '\u0327']), ('\u0160', &['\x53', '\u030c']), ('\u0161', &['\x73',
- '\u030c']), ('\u0162', &['\x54', '\u0327']), ('\u0163', &['\x74', '\u0327']), ('\u0164',
- &['\x54', '\u030c']), ('\u0165', &['\x74', '\u030c']), ('\u0168', &['\x55', '\u0303']),
- ('\u0169', &['\x75', '\u0303']), ('\u016a', &['\x55', '\u0304']), ('\u016b', &['\x75',
- '\u0304']), ('\u016c', &['\x55', '\u0306']), ('\u016d', &['\x75', '\u0306']), ('\u016e',
- &['\x55', '\u030a']), ('\u016f', &['\x75', '\u030a']), ('\u0170', &['\x55', '\u030b']),
- ('\u0171', &['\x75', '\u030b']), ('\u0172', &['\x55', '\u0328']), ('\u0173', &['\x75',
- '\u0328']), ('\u0174', &['\x57', '\u0302']), ('\u0175', &['\x77', '\u0302']), ('\u0176',
- &['\x59', '\u0302']), ('\u0177', &['\x79', '\u0302']), ('\u0178', &['\x59', '\u0308']),
- ('\u0179', &['\x5a', '\u0301']), ('\u017a', &['\x7a', '\u0301']), ('\u017b', &['\x5a',
- '\u0307']), ('\u017c', &['\x7a', '\u0307']), ('\u017d', &['\x5a', '\u030c']), ('\u017e',
- &['\x7a', '\u030c']), ('\u01a0', &['\x4f', '\u031b']), ('\u01a1', &['\x6f', '\u031b']),
- ('\u01af', &['\x55', '\u031b']), ('\u01b0', &['\x75', '\u031b']), ('\u01cd', &['\x41',
- '\u030c']), ('\u01ce', &['\x61', '\u030c']), ('\u01cf', &['\x49', '\u030c']), ('\u01d0',
- &['\x69', '\u030c']), ('\u01d1', &['\x4f', '\u030c']), ('\u01d2', &['\x6f', '\u030c']),
- ('\u01d3', &['\x55', '\u030c']), ('\u01d4', &['\x75', '\u030c']), ('\u01d5', &['\xdc',
- '\u0304']), ('\u01d6', &['\xfc', '\u0304']), ('\u01d7', &['\xdc', '\u0301']), ('\u01d8',
- &['\xfc', '\u0301']), ('\u01d9', &['\xdc', '\u030c']), ('\u01da', &['\xfc', '\u030c']),
- ('\u01db', &['\xdc', '\u0300']), ('\u01dc', &['\xfc', '\u0300']), ('\u01de', &['\xc4',
- '\u0304']), ('\u01df', &['\xe4', '\u0304']), ('\u01e0', &['\u0226', '\u0304']), ('\u01e1',
- &['\u0227', '\u0304']), ('\u01e2', &['\xc6', '\u0304']), ('\u01e3', &['\xe6', '\u0304']),
- ('\u01e6', &['\x47', '\u030c']), ('\u01e7', &['\x67', '\u030c']), ('\u01e8', &['\x4b',
- '\u030c']), ('\u01e9', &['\x6b', '\u030c']), ('\u01ea', &['\x4f', '\u0328']), ('\u01eb',
- &['\x6f', '\u0328']), ('\u01ec', &['\u01ea', '\u0304']), ('\u01ed', &['\u01eb', '\u0304']),
- ('\u01ee', &['\u01b7', '\u030c']), ('\u01ef', &['\u0292', '\u030c']), ('\u01f0', &['\x6a',
- '\u030c']), ('\u01f4', &['\x47', '\u0301']), ('\u01f5', &['\x67', '\u0301']), ('\u01f8',
- &['\x4e', '\u0300']), ('\u01f9', &['\x6e', '\u0300']), ('\u01fa', &['\xc5', '\u0301']),
- ('\u01fb', &['\xe5', '\u0301']), ('\u01fc', &['\xc6', '\u0301']), ('\u01fd', &['\xe6',
- '\u0301']), ('\u01fe', &['\xd8', '\u0301']), ('\u01ff', &['\xf8', '\u0301']), ('\u0200',
- &['\x41', '\u030f']), ('\u0201', &['\x61', '\u030f']), ('\u0202', &['\x41', '\u0311']),
- ('\u0203', &['\x61', '\u0311']), ('\u0204', &['\x45', '\u030f']), ('\u0205', &['\x65',
- '\u030f']), ('\u0206', &['\x45', '\u0311']), ('\u0207', &['\x65', '\u0311']), ('\u0208',
- &['\x49', '\u030f']), ('\u0209', &['\x69', '\u030f']), ('\u020a', &['\x49', '\u0311']),
- ('\u020b', &['\x69', '\u0311']), ('\u020c', &['\x4f', '\u030f']), ('\u020d', &['\x6f',
- '\u030f']), ('\u020e', &['\x4f', '\u0311']), ('\u020f', &['\x6f', '\u0311']), ('\u0210',
- &['\x52', '\u030f']), ('\u0211', &['\x72', '\u030f']), ('\u0212', &['\x52', '\u0311']),
- ('\u0213', &['\x72', '\u0311']), ('\u0214', &['\x55', '\u030f']), ('\u0215', &['\x75',
- '\u030f']), ('\u0216', &['\x55', '\u0311']), ('\u0217', &['\x75', '\u0311']), ('\u0218',
- &['\x53', '\u0326']), ('\u0219', &['\x73', '\u0326']), ('\u021a', &['\x54', '\u0326']),
- ('\u021b', &['\x74', '\u0326']), ('\u021e', &['\x48', '\u030c']), ('\u021f', &['\x68',
- '\u030c']), ('\u0226', &['\x41', '\u0307']), ('\u0227', &['\x61', '\u0307']), ('\u0228',
- &['\x45', '\u0327']), ('\u0229', &['\x65', '\u0327']), ('\u022a', &['\xd6', '\u0304']),
- ('\u022b', &['\xf6', '\u0304']), ('\u022c', &['\xd5', '\u0304']), ('\u022d', &['\xf5',
- '\u0304']), ('\u022e', &['\x4f', '\u0307']), ('\u022f', &['\x6f', '\u0307']), ('\u0230',
- &['\u022e', '\u0304']), ('\u0231', &['\u022f', '\u0304']), ('\u0232', &['\x59', '\u0304']),
- ('\u0233', &['\x79', '\u0304']), ('\u0340', &['\u0300']), ('\u0341', &['\u0301']),
- ('\u0343', &['\u0313']), ('\u0344', &['\u0308', '\u0301']), ('\u0374', &['\u02b9']),
- ('\u037e', &['\x3b']), ('\u0385', &['\xa8', '\u0301']), ('\u0386', &['\u0391', '\u0301']),
- ('\u0387', &['\xb7']), ('\u0388', &['\u0395', '\u0301']), ('\u0389', &['\u0397', '\u0301']),
- ('\u038a', &['\u0399', '\u0301']), ('\u038c', &['\u039f', '\u0301']), ('\u038e', &['\u03a5',
- '\u0301']), ('\u038f', &['\u03a9', '\u0301']), ('\u0390', &['\u03ca', '\u0301']), ('\u03aa',
- &['\u0399', '\u0308']), ('\u03ab', &['\u03a5', '\u0308']), ('\u03ac', &['\u03b1',
- '\u0301']), ('\u03ad', &['\u03b5', '\u0301']), ('\u03ae', &['\u03b7', '\u0301']), ('\u03af',
- &['\u03b9', '\u0301']), ('\u03b0', &['\u03cb', '\u0301']), ('\u03ca', &['\u03b9',
- '\u0308']), ('\u03cb', &['\u03c5', '\u0308']), ('\u03cc', &['\u03bf', '\u0301']), ('\u03cd',
- &['\u03c5', '\u0301']), ('\u03ce', &['\u03c9', '\u0301']), ('\u03d3', &['\u03d2',
- '\u0301']), ('\u03d4', &['\u03d2', '\u0308']), ('\u0400', &['\u0415', '\u0300']), ('\u0401',
- &['\u0415', '\u0308']), ('\u0403', &['\u0413', '\u0301']), ('\u0407', &['\u0406',
- '\u0308']), ('\u040c', &['\u041a', '\u0301']), ('\u040d', &['\u0418', '\u0300']), ('\u040e',
- &['\u0423', '\u0306']), ('\u0419', &['\u0418', '\u0306']), ('\u0439', &['\u0438',
- '\u0306']), ('\u0450', &['\u0435', '\u0300']), ('\u0451', &['\u0435', '\u0308']), ('\u0453',
- &['\u0433', '\u0301']), ('\u0457', &['\u0456', '\u0308']), ('\u045c', &['\u043a',
- '\u0301']), ('\u045d', &['\u0438', '\u0300']), ('\u045e', &['\u0443', '\u0306']), ('\u0476',
- &['\u0474', '\u030f']), ('\u0477', &['\u0475', '\u030f']), ('\u04c1', &['\u0416',
- '\u0306']), ('\u04c2', &['\u0436', '\u0306']), ('\u04d0', &['\u0410', '\u0306']), ('\u04d1',
- &['\u0430', '\u0306']), ('\u04d2', &['\u0410', '\u0308']), ('\u04d3', &['\u0430',
- '\u0308']), ('\u04d6', &['\u0415', '\u0306']), ('\u04d7', &['\u0435', '\u0306']), ('\u04da',
- &['\u04d8', '\u0308']), ('\u04db', &['\u04d9', '\u0308']), ('\u04dc', &['\u0416',
- '\u0308']), ('\u04dd', &['\u0436', '\u0308']), ('\u04de', &['\u0417', '\u0308']), ('\u04df',
- &['\u0437', '\u0308']), ('\u04e2', &['\u0418', '\u0304']), ('\u04e3', &['\u0438',
- '\u0304']), ('\u04e4', &['\u0418', '\u0308']), ('\u04e5', &['\u0438', '\u0308']), ('\u04e6',
- &['\u041e', '\u0308']), ('\u04e7', &['\u043e', '\u0308']), ('\u04ea', &['\u04e8',
- '\u0308']), ('\u04eb', &['\u04e9', '\u0308']), ('\u04ec', &['\u042d', '\u0308']), ('\u04ed',
- &['\u044d', '\u0308']), ('\u04ee', &['\u0423', '\u0304']), ('\u04ef', &['\u0443',
- '\u0304']), ('\u04f0', &['\u0423', '\u0308']), ('\u04f1', &['\u0443', '\u0308']), ('\u04f2',
- &['\u0423', '\u030b']), ('\u04f3', &['\u0443', '\u030b']), ('\u04f4', &['\u0427',
- '\u0308']), ('\u04f5', &['\u0447', '\u0308']), ('\u04f8', &['\u042b', '\u0308']), ('\u04f9',
- &['\u044b', '\u0308']), ('\u0622', &['\u0627', '\u0653']), ('\u0623', &['\u0627',
- '\u0654']), ('\u0624', &['\u0648', '\u0654']), ('\u0625', &['\u0627', '\u0655']), ('\u0626',
- &['\u064a', '\u0654']), ('\u06c0', &['\u06d5', '\u0654']), ('\u06c2', &['\u06c1',
- '\u0654']), ('\u06d3', &['\u06d2', '\u0654']), ('\u0929', &['\u0928', '\u093c']), ('\u0931',
- &['\u0930', '\u093c']), ('\u0934', &['\u0933', '\u093c']), ('\u0958', &['\u0915',
- '\u093c']), ('\u0959', &['\u0916', '\u093c']), ('\u095a', &['\u0917', '\u093c']), ('\u095b',
- &['\u091c', '\u093c']), ('\u095c', &['\u0921', '\u093c']), ('\u095d', &['\u0922',
- '\u093c']), ('\u095e', &['\u092b', '\u093c']), ('\u095f', &['\u092f', '\u093c']), ('\u09cb',
- &['\u09c7', '\u09be']), ('\u09cc', &['\u09c7', '\u09d7']), ('\u09dc', &['\u09a1',
- '\u09bc']), ('\u09dd', &['\u09a2', '\u09bc']), ('\u09df', &['\u09af', '\u09bc']), ('\u0a33',
- &['\u0a32', '\u0a3c']), ('\u0a36', &['\u0a38', '\u0a3c']), ('\u0a59', &['\u0a16',
- '\u0a3c']), ('\u0a5a', &['\u0a17', '\u0a3c']), ('\u0a5b', &['\u0a1c', '\u0a3c']), ('\u0a5e',
- &['\u0a2b', '\u0a3c']), ('\u0b48', &['\u0b47', '\u0b56']), ('\u0b4b', &['\u0b47',
- '\u0b3e']), ('\u0b4c', &['\u0b47', '\u0b57']), ('\u0b5c', &['\u0b21', '\u0b3c']), ('\u0b5d',
- &['\u0b22', '\u0b3c']), ('\u0b94', &['\u0b92', '\u0bd7']), ('\u0bca', &['\u0bc6',
- '\u0bbe']), ('\u0bcb', &['\u0bc7', '\u0bbe']), ('\u0bcc', &['\u0bc6', '\u0bd7']), ('\u0c48',
- &['\u0c46', '\u0c56']), ('\u0cc0', &['\u0cbf', '\u0cd5']), ('\u0cc7', &['\u0cc6',
- '\u0cd5']), ('\u0cc8', &['\u0cc6', '\u0cd6']), ('\u0cca', &['\u0cc6', '\u0cc2']), ('\u0ccb',
- &['\u0cca', '\u0cd5']), ('\u0d4a', &['\u0d46', '\u0d3e']), ('\u0d4b', &['\u0d47',
- '\u0d3e']), ('\u0d4c', &['\u0d46', '\u0d57']), ('\u0dda', &['\u0dd9', '\u0dca']), ('\u0ddc',
- &['\u0dd9', '\u0dcf']), ('\u0ddd', &['\u0ddc', '\u0dca']), ('\u0dde', &['\u0dd9',
- '\u0ddf']), ('\u0f43', &['\u0f42', '\u0fb7']), ('\u0f4d', &['\u0f4c', '\u0fb7']), ('\u0f52',
- &['\u0f51', '\u0fb7']), ('\u0f57', &['\u0f56', '\u0fb7']), ('\u0f5c', &['\u0f5b',
- '\u0fb7']), ('\u0f69', &['\u0f40', '\u0fb5']), ('\u0f73', &['\u0f71', '\u0f72']), ('\u0f75',
- &['\u0f71', '\u0f74']), ('\u0f76', &['\u0fb2', '\u0f80']), ('\u0f78', &['\u0fb3',
- '\u0f80']), ('\u0f81', &['\u0f71', '\u0f80']), ('\u0f93', &['\u0f92', '\u0fb7']), ('\u0f9d',
- &['\u0f9c', '\u0fb7']), ('\u0fa2', &['\u0fa1', '\u0fb7']), ('\u0fa7', &['\u0fa6',
- '\u0fb7']), ('\u0fac', &['\u0fab', '\u0fb7']), ('\u0fb9', &['\u0f90', '\u0fb5']), ('\u1026',
- &['\u1025', '\u102e']), ('\u1b06', &['\u1b05', '\u1b35']), ('\u1b08', &['\u1b07',
- '\u1b35']), ('\u1b0a', &['\u1b09', '\u1b35']), ('\u1b0c', &['\u1b0b', '\u1b35']), ('\u1b0e',
- &['\u1b0d', '\u1b35']), ('\u1b12', &['\u1b11', '\u1b35']), ('\u1b3b', &['\u1b3a',
- '\u1b35']), ('\u1b3d', &['\u1b3c', '\u1b35']), ('\u1b40', &['\u1b3e', '\u1b35']), ('\u1b41',
- &['\u1b3f', '\u1b35']), ('\u1b43', &['\u1b42', '\u1b35']), ('\u1e00', &['\x41', '\u0325']),
- ('\u1e01', &['\x61', '\u0325']), ('\u1e02', &['\x42', '\u0307']), ('\u1e03', &['\x62',
- '\u0307']), ('\u1e04', &['\x42', '\u0323']), ('\u1e05', &['\x62', '\u0323']), ('\u1e06',
- &['\x42', '\u0331']), ('\u1e07', &['\x62', '\u0331']), ('\u1e08', &['\xc7', '\u0301']),
- ('\u1e09', &['\xe7', '\u0301']), ('\u1e0a', &['\x44', '\u0307']), ('\u1e0b', &['\x64',
- '\u0307']), ('\u1e0c', &['\x44', '\u0323']), ('\u1e0d', &['\x64', '\u0323']), ('\u1e0e',
- &['\x44', '\u0331']), ('\u1e0f', &['\x64', '\u0331']), ('\u1e10', &['\x44', '\u0327']),
- ('\u1e11', &['\x64', '\u0327']), ('\u1e12', &['\x44', '\u032d']), ('\u1e13', &['\x64',
- '\u032d']), ('\u1e14', &['\u0112', '\u0300']), ('\u1e15', &['\u0113', '\u0300']), ('\u1e16',
- &['\u0112', '\u0301']), ('\u1e17', &['\u0113', '\u0301']), ('\u1e18', &['\x45', '\u032d']),
- ('\u1e19', &['\x65', '\u032d']), ('\u1e1a', &['\x45', '\u0330']), ('\u1e1b', &['\x65',
- '\u0330']), ('\u1e1c', &['\u0228', '\u0306']), ('\u1e1d', &['\u0229', '\u0306']), ('\u1e1e',
- &['\x46', '\u0307']), ('\u1e1f', &['\x66', '\u0307']), ('\u1e20', &['\x47', '\u0304']),
- ('\u1e21', &['\x67', '\u0304']), ('\u1e22', &['\x48', '\u0307']), ('\u1e23', &['\x68',
- '\u0307']), ('\u1e24', &['\x48', '\u0323']), ('\u1e25', &['\x68', '\u0323']), ('\u1e26',
- &['\x48', '\u0308']), ('\u1e27', &['\x68', '\u0308']), ('\u1e28', &['\x48', '\u0327']),
- ('\u1e29', &['\x68', '\u0327']), ('\u1e2a', &['\x48', '\u032e']), ('\u1e2b', &['\x68',
- '\u032e']), ('\u1e2c', &['\x49', '\u0330']), ('\u1e2d', &['\x69', '\u0330']), ('\u1e2e',
- &['\xcf', '\u0301']), ('\u1e2f', &['\xef', '\u0301']), ('\u1e30', &['\x4b', '\u0301']),
- ('\u1e31', &['\x6b', '\u0301']), ('\u1e32', &['\x4b', '\u0323']), ('\u1e33', &['\x6b',
- '\u0323']), ('\u1e34', &['\x4b', '\u0331']), ('\u1e35', &['\x6b', '\u0331']), ('\u1e36',
- &['\x4c', '\u0323']), ('\u1e37', &['\x6c', '\u0323']), ('\u1e38', &['\u1e36', '\u0304']),
- ('\u1e39', &['\u1e37', '\u0304']), ('\u1e3a', &['\x4c', '\u0331']), ('\u1e3b', &['\x6c',
- '\u0331']), ('\u1e3c', &['\x4c', '\u032d']), ('\u1e3d', &['\x6c', '\u032d']), ('\u1e3e',
- &['\x4d', '\u0301']), ('\u1e3f', &['\x6d', '\u0301']), ('\u1e40', &['\x4d', '\u0307']),
- ('\u1e41', &['\x6d', '\u0307']), ('\u1e42', &['\x4d', '\u0323']), ('\u1e43', &['\x6d',
- '\u0323']), ('\u1e44', &['\x4e', '\u0307']), ('\u1e45', &['\x6e', '\u0307']), ('\u1e46',
- &['\x4e', '\u0323']), ('\u1e47', &['\x6e', '\u0323']), ('\u1e48', &['\x4e', '\u0331']),
- ('\u1e49', &['\x6e', '\u0331']), ('\u1e4a', &['\x4e', '\u032d']), ('\u1e4b', &['\x6e',
- '\u032d']), ('\u1e4c', &['\xd5', '\u0301']), ('\u1e4d', &['\xf5', '\u0301']), ('\u1e4e',
- &['\xd5', '\u0308']), ('\u1e4f', &['\xf5', '\u0308']), ('\u1e50', &['\u014c', '\u0300']),
- ('\u1e51', &['\u014d', '\u0300']), ('\u1e52', &['\u014c', '\u0301']), ('\u1e53', &['\u014d',
- '\u0301']), ('\u1e54', &['\x50', '\u0301']), ('\u1e55', &['\x70', '\u0301']), ('\u1e56',
- &['\x50', '\u0307']), ('\u1e57', &['\x70', '\u0307']), ('\u1e58', &['\x52', '\u0307']),
- ('\u1e59', &['\x72', '\u0307']), ('\u1e5a', &['\x52', '\u0323']), ('\u1e5b', &['\x72',
- '\u0323']), ('\u1e5c', &['\u1e5a', '\u0304']), ('\u1e5d', &['\u1e5b', '\u0304']), ('\u1e5e',
- &['\x52', '\u0331']), ('\u1e5f', &['\x72', '\u0331']), ('\u1e60', &['\x53', '\u0307']),
- ('\u1e61', &['\x73', '\u0307']), ('\u1e62', &['\x53', '\u0323']), ('\u1e63', &['\x73',
- '\u0323']), ('\u1e64', &['\u015a', '\u0307']), ('\u1e65', &['\u015b', '\u0307']), ('\u1e66',
- &['\u0160', '\u0307']), ('\u1e67', &['\u0161', '\u0307']), ('\u1e68', &['\u1e62',
- '\u0307']), ('\u1e69', &['\u1e63', '\u0307']), ('\u1e6a', &['\x54', '\u0307']), ('\u1e6b',
- &['\x74', '\u0307']), ('\u1e6c', &['\x54', '\u0323']), ('\u1e6d', &['\x74', '\u0323']),
- ('\u1e6e', &['\x54', '\u0331']), ('\u1e6f', &['\x74', '\u0331']), ('\u1e70', &['\x54',
- '\u032d']), ('\u1e71', &['\x74', '\u032d']), ('\u1e72', &['\x55', '\u0324']), ('\u1e73',
- &['\x75', '\u0324']), ('\u1e74', &['\x55', '\u0330']), ('\u1e75', &['\x75', '\u0330']),
- ('\u1e76', &['\x55', '\u032d']), ('\u1e77', &['\x75', '\u032d']), ('\u1e78', &['\u0168',
- '\u0301']), ('\u1e79', &['\u0169', '\u0301']), ('\u1e7a', &['\u016a', '\u0308']), ('\u1e7b',
- &['\u016b', '\u0308']), ('\u1e7c', &['\x56', '\u0303']), ('\u1e7d', &['\x76', '\u0303']),
- ('\u1e7e', &['\x56', '\u0323']), ('\u1e7f', &['\x76', '\u0323']), ('\u1e80', &['\x57',
- '\u0300']), ('\u1e81', &['\x77', '\u0300']), ('\u1e82', &['\x57', '\u0301']), ('\u1e83',
- &['\x77', '\u0301']), ('\u1e84', &['\x57', '\u0308']), ('\u1e85', &['\x77', '\u0308']),
- ('\u1e86', &['\x57', '\u0307']), ('\u1e87', &['\x77', '\u0307']), ('\u1e88', &['\x57',
- '\u0323']), ('\u1e89', &['\x77', '\u0323']), ('\u1e8a', &['\x58', '\u0307']), ('\u1e8b',
- &['\x78', '\u0307']), ('\u1e8c', &['\x58', '\u0308']), ('\u1e8d', &['\x78', '\u0308']),
- ('\u1e8e', &['\x59', '\u0307']), ('\u1e8f', &['\x79', '\u0307']), ('\u1e90', &['\x5a',
- '\u0302']), ('\u1e91', &['\x7a', '\u0302']), ('\u1e92', &['\x5a', '\u0323']), ('\u1e93',
- &['\x7a', '\u0323']), ('\u1e94', &['\x5a', '\u0331']), ('\u1e95', &['\x7a', '\u0331']),
- ('\u1e96', &['\x68', '\u0331']), ('\u1e97', &['\x74', '\u0308']), ('\u1e98', &['\x77',
- '\u030a']), ('\u1e99', &['\x79', '\u030a']), ('\u1e9b', &['\u017f', '\u0307']), ('\u1ea0',
- &['\x41', '\u0323']), ('\u1ea1', &['\x61', '\u0323']), ('\u1ea2', &['\x41', '\u0309']),
- ('\u1ea3', &['\x61', '\u0309']), ('\u1ea4', &['\xc2', '\u0301']), ('\u1ea5', &['\xe2',
- '\u0301']), ('\u1ea6', &['\xc2', '\u0300']), ('\u1ea7', &['\xe2', '\u0300']), ('\u1ea8',
- &['\xc2', '\u0309']), ('\u1ea9', &['\xe2', '\u0309']), ('\u1eaa', &['\xc2', '\u0303']),
- ('\u1eab', &['\xe2', '\u0303']), ('\u1eac', &['\u1ea0', '\u0302']), ('\u1ead', &['\u1ea1',
- '\u0302']), ('\u1eae', &['\u0102', '\u0301']), ('\u1eaf', &['\u0103', '\u0301']), ('\u1eb0',
- &['\u0102', '\u0300']), ('\u1eb1', &['\u0103', '\u0300']), ('\u1eb2', &['\u0102',
- '\u0309']), ('\u1eb3', &['\u0103', '\u0309']), ('\u1eb4', &['\u0102', '\u0303']), ('\u1eb5',
- &['\u0103', '\u0303']), ('\u1eb6', &['\u1ea0', '\u0306']), ('\u1eb7', &['\u1ea1',
- '\u0306']), ('\u1eb8', &['\x45', '\u0323']), ('\u1eb9', &['\x65', '\u0323']), ('\u1eba',
- &['\x45', '\u0309']), ('\u1ebb', &['\x65', '\u0309']), ('\u1ebc', &['\x45', '\u0303']),
- ('\u1ebd', &['\x65', '\u0303']), ('\u1ebe', &['\xca', '\u0301']), ('\u1ebf', &['\xea',
- '\u0301']), ('\u1ec0', &['\xca', '\u0300']), ('\u1ec1', &['\xea', '\u0300']), ('\u1ec2',
- &['\xca', '\u0309']), ('\u1ec3', &['\xea', '\u0309']), ('\u1ec4', &['\xca', '\u0303']),
- ('\u1ec5', &['\xea', '\u0303']), ('\u1ec6', &['\u1eb8', '\u0302']), ('\u1ec7', &['\u1eb9',
- '\u0302']), ('\u1ec8', &['\x49', '\u0309']), ('\u1ec9', &['\x69', '\u0309']), ('\u1eca',
- &['\x49', '\u0323']), ('\u1ecb', &['\x69', '\u0323']), ('\u1ecc', &['\x4f', '\u0323']),
- ('\u1ecd', &['\x6f', '\u0323']), ('\u1ece', &['\x4f', '\u0309']), ('\u1ecf', &['\x6f',
- '\u0309']), ('\u1ed0', &['\xd4', '\u0301']), ('\u1ed1', &['\xf4', '\u0301']), ('\u1ed2',
- &['\xd4', '\u0300']), ('\u1ed3', &['\xf4', '\u0300']), ('\u1ed4', &['\xd4', '\u0309']),
- ('\u1ed5', &['\xf4', '\u0309']), ('\u1ed6', &['\xd4', '\u0303']), ('\u1ed7', &['\xf4',
- '\u0303']), ('\u1ed8', &['\u1ecc', '\u0302']), ('\u1ed9', &['\u1ecd', '\u0302']), ('\u1eda',
- &['\u01a0', '\u0301']), ('\u1edb', &['\u01a1', '\u0301']), ('\u1edc', &['\u01a0',
- '\u0300']), ('\u1edd', &['\u01a1', '\u0300']), ('\u1ede', &['\u01a0', '\u0309']), ('\u1edf',
- &['\u01a1', '\u0309']), ('\u1ee0', &['\u01a0', '\u0303']), ('\u1ee1', &['\u01a1',
- '\u0303']), ('\u1ee2', &['\u01a0', '\u0323']), ('\u1ee3', &['\u01a1', '\u0323']), ('\u1ee4',
- &['\x55', '\u0323']), ('\u1ee5', &['\x75', '\u0323']), ('\u1ee6', &['\x55', '\u0309']),
- ('\u1ee7', &['\x75', '\u0309']), ('\u1ee8', &['\u01af', '\u0301']), ('\u1ee9', &['\u01b0',
- '\u0301']), ('\u1eea', &['\u01af', '\u0300']), ('\u1eeb', &['\u01b0', '\u0300']), ('\u1eec',
- &['\u01af', '\u0309']), ('\u1eed', &['\u01b0', '\u0309']), ('\u1eee', &['\u01af',
- '\u0303']), ('\u1eef', &['\u01b0', '\u0303']), ('\u1ef0', &['\u01af', '\u0323']), ('\u1ef1',
- &['\u01b0', '\u0323']), ('\u1ef2', &['\x59', '\u0300']), ('\u1ef3', &['\x79', '\u0300']),
- ('\u1ef4', &['\x59', '\u0323']), ('\u1ef5', &['\x79', '\u0323']), ('\u1ef6', &['\x59',
- '\u0309']), ('\u1ef7', &['\x79', '\u0309']), ('\u1ef8', &['\x59', '\u0303']), ('\u1ef9',
- &['\x79', '\u0303']), ('\u1f00', &['\u03b1', '\u0313']), ('\u1f01', &['\u03b1', '\u0314']),
- ('\u1f02', &['\u1f00', '\u0300']), ('\u1f03', &['\u1f01', '\u0300']), ('\u1f04', &['\u1f00',
- '\u0301']), ('\u1f05', &['\u1f01', '\u0301']), ('\u1f06', &['\u1f00', '\u0342']), ('\u1f07',
- &['\u1f01', '\u0342']), ('\u1f08', &['\u0391', '\u0313']), ('\u1f09', &['\u0391',
- '\u0314']), ('\u1f0a', &['\u1f08', '\u0300']), ('\u1f0b', &['\u1f09', '\u0300']), ('\u1f0c',
- &['\u1f08', '\u0301']), ('\u1f0d', &['\u1f09', '\u0301']), ('\u1f0e', &['\u1f08',
- '\u0342']), ('\u1f0f', &['\u1f09', '\u0342']), ('\u1f10', &['\u03b5', '\u0313']), ('\u1f11',
- &['\u03b5', '\u0314']), ('\u1f12', &['\u1f10', '\u0300']), ('\u1f13', &['\u1f11',
- '\u0300']), ('\u1f14', &['\u1f10', '\u0301']), ('\u1f15', &['\u1f11', '\u0301']), ('\u1f18',
- &['\u0395', '\u0313']), ('\u1f19', &['\u0395', '\u0314']), ('\u1f1a', &['\u1f18',
- '\u0300']), ('\u1f1b', &['\u1f19', '\u0300']), ('\u1f1c', &['\u1f18', '\u0301']), ('\u1f1d',
- &['\u1f19', '\u0301']), ('\u1f20', &['\u03b7', '\u0313']), ('\u1f21', &['\u03b7',
- '\u0314']), ('\u1f22', &['\u1f20', '\u0300']), ('\u1f23', &['\u1f21', '\u0300']), ('\u1f24',
- &['\u1f20', '\u0301']), ('\u1f25', &['\u1f21', '\u0301']), ('\u1f26', &['\u1f20',
- '\u0342']), ('\u1f27', &['\u1f21', '\u0342']), ('\u1f28', &['\u0397', '\u0313']), ('\u1f29',
- &['\u0397', '\u0314']), ('\u1f2a', &['\u1f28', '\u0300']), ('\u1f2b', &['\u1f29',
- '\u0300']), ('\u1f2c', &['\u1f28', '\u0301']), ('\u1f2d', &['\u1f29', '\u0301']), ('\u1f2e',
- &['\u1f28', '\u0342']), ('\u1f2f', &['\u1f29', '\u0342']), ('\u1f30', &['\u03b9',
- '\u0313']), ('\u1f31', &['\u03b9', '\u0314']), ('\u1f32', &['\u1f30', '\u0300']), ('\u1f33',
- &['\u1f31', '\u0300']), ('\u1f34', &['\u1f30', '\u0301']), ('\u1f35', &['\u1f31',
- '\u0301']), ('\u1f36', &['\u1f30', '\u0342']), ('\u1f37', &['\u1f31', '\u0342']), ('\u1f38',
- &['\u0399', '\u0313']), ('\u1f39', &['\u0399', '\u0314']), ('\u1f3a', &['\u1f38',
- '\u0300']), ('\u1f3b', &['\u1f39', '\u0300']), ('\u1f3c', &['\u1f38', '\u0301']), ('\u1f3d',
- &['\u1f39', '\u0301']), ('\u1f3e', &['\u1f38', '\u0342']), ('\u1f3f', &['\u1f39',
- '\u0342']), ('\u1f40', &['\u03bf', '\u0313']), ('\u1f41', &['\u03bf', '\u0314']), ('\u1f42',
- &['\u1f40', '\u0300']), ('\u1f43', &['\u1f41', '\u0300']), ('\u1f44', &['\u1f40',
- '\u0301']), ('\u1f45', &['\u1f41', '\u0301']), ('\u1f48', &['\u039f', '\u0313']), ('\u1f49',
- &['\u039f', '\u0314']), ('\u1f4a', &['\u1f48', '\u0300']), ('\u1f4b', &['\u1f49',
- '\u0300']), ('\u1f4c', &['\u1f48', '\u0301']), ('\u1f4d', &['\u1f49', '\u0301']), ('\u1f50',
- &['\u03c5', '\u0313']), ('\u1f51', &['\u03c5', '\u0314']), ('\u1f52', &['\u1f50',
- '\u0300']), ('\u1f53', &['\u1f51', '\u0300']), ('\u1f54', &['\u1f50', '\u0301']), ('\u1f55',
- &['\u1f51', '\u0301']), ('\u1f56', &['\u1f50', '\u0342']), ('\u1f57', &['\u1f51',
- '\u0342']), ('\u1f59', &['\u03a5', '\u0314']), ('\u1f5b', &['\u1f59', '\u0300']), ('\u1f5d',
- &['\u1f59', '\u0301']), ('\u1f5f', &['\u1f59', '\u0342']), ('\u1f60', &['\u03c9',
- '\u0313']), ('\u1f61', &['\u03c9', '\u0314']), ('\u1f62', &['\u1f60', '\u0300']), ('\u1f63',
- &['\u1f61', '\u0300']), ('\u1f64', &['\u1f60', '\u0301']), ('\u1f65', &['\u1f61',
- '\u0301']), ('\u1f66', &['\u1f60', '\u0342']), ('\u1f67', &['\u1f61', '\u0342']), ('\u1f68',
- &['\u03a9', '\u0313']), ('\u1f69', &['\u03a9', '\u0314']), ('\u1f6a', &['\u1f68',
- '\u0300']), ('\u1f6b', &['\u1f69', '\u0300']), ('\u1f6c', &['\u1f68', '\u0301']), ('\u1f6d',
- &['\u1f69', '\u0301']), ('\u1f6e', &['\u1f68', '\u0342']), ('\u1f6f', &['\u1f69',
- '\u0342']), ('\u1f70', &['\u03b1', '\u0300']), ('\u1f71', &['\u03ac']), ('\u1f72',
- &['\u03b5', '\u0300']), ('\u1f73', &['\u03ad']), ('\u1f74', &['\u03b7', '\u0300']),
- ('\u1f75', &['\u03ae']), ('\u1f76', &['\u03b9', '\u0300']), ('\u1f77', &['\u03af']),
- ('\u1f78', &['\u03bf', '\u0300']), ('\u1f79', &['\u03cc']), ('\u1f7a', &['\u03c5',
- '\u0300']), ('\u1f7b', &['\u03cd']), ('\u1f7c', &['\u03c9', '\u0300']), ('\u1f7d',
- &['\u03ce']), ('\u1f80', &['\u1f00', '\u0345']), ('\u1f81', &['\u1f01', '\u0345']),
- ('\u1f82', &['\u1f02', '\u0345']), ('\u1f83', &['\u1f03', '\u0345']), ('\u1f84', &['\u1f04',
- '\u0345']), ('\u1f85', &['\u1f05', '\u0345']), ('\u1f86', &['\u1f06', '\u0345']), ('\u1f87',
- &['\u1f07', '\u0345']), ('\u1f88', &['\u1f08', '\u0345']), ('\u1f89', &['\u1f09',
- '\u0345']), ('\u1f8a', &['\u1f0a', '\u0345']), ('\u1f8b', &['\u1f0b', '\u0345']), ('\u1f8c',
- &['\u1f0c', '\u0345']), ('\u1f8d', &['\u1f0d', '\u0345']), ('\u1f8e', &['\u1f0e',
- '\u0345']), ('\u1f8f', &['\u1f0f', '\u0345']), ('\u1f90', &['\u1f20', '\u0345']), ('\u1f91',
- &['\u1f21', '\u0345']), ('\u1f92', &['\u1f22', '\u0345']), ('\u1f93', &['\u1f23',
- '\u0345']), ('\u1f94', &['\u1f24', '\u0345']), ('\u1f95', &['\u1f25', '\u0345']), ('\u1f96',
- &['\u1f26', '\u0345']), ('\u1f97', &['\u1f27', '\u0345']), ('\u1f98', &['\u1f28',
- '\u0345']), ('\u1f99', &['\u1f29', '\u0345']), ('\u1f9a', &['\u1f2a', '\u0345']), ('\u1f9b',
- &['\u1f2b', '\u0345']), ('\u1f9c', &['\u1f2c', '\u0345']), ('\u1f9d', &['\u1f2d',
- '\u0345']), ('\u1f9e', &['\u1f2e', '\u0345']), ('\u1f9f', &['\u1f2f', '\u0345']), ('\u1fa0',
- &['\u1f60', '\u0345']), ('\u1fa1', &['\u1f61', '\u0345']), ('\u1fa2', &['\u1f62',
- '\u0345']), ('\u1fa3', &['\u1f63', '\u0345']), ('\u1fa4', &['\u1f64', '\u0345']), ('\u1fa5',
- &['\u1f65', '\u0345']), ('\u1fa6', &['\u1f66', '\u0345']), ('\u1fa7', &['\u1f67',
- '\u0345']), ('\u1fa8', &['\u1f68', '\u0345']), ('\u1fa9', &['\u1f69', '\u0345']), ('\u1faa',
- &['\u1f6a', '\u0345']), ('\u1fab', &['\u1f6b', '\u0345']), ('\u1fac', &['\u1f6c',
- '\u0345']), ('\u1fad', &['\u1f6d', '\u0345']), ('\u1fae', &['\u1f6e', '\u0345']), ('\u1faf',
- &['\u1f6f', '\u0345']), ('\u1fb0', &['\u03b1', '\u0306']), ('\u1fb1', &['\u03b1',
- '\u0304']), ('\u1fb2', &['\u1f70', '\u0345']), ('\u1fb3', &['\u03b1', '\u0345']), ('\u1fb4',
- &['\u03ac', '\u0345']), ('\u1fb6', &['\u03b1', '\u0342']), ('\u1fb7', &['\u1fb6',
- '\u0345']), ('\u1fb8', &['\u0391', '\u0306']), ('\u1fb9', &['\u0391', '\u0304']), ('\u1fba',
- &['\u0391', '\u0300']), ('\u1fbb', &['\u0386']), ('\u1fbc', &['\u0391', '\u0345']),
- ('\u1fbe', &['\u03b9']), ('\u1fc1', &['\xa8', '\u0342']), ('\u1fc2', &['\u1f74', '\u0345']),
- ('\u1fc3', &['\u03b7', '\u0345']), ('\u1fc4', &['\u03ae', '\u0345']), ('\u1fc6', &['\u03b7',
- '\u0342']), ('\u1fc7', &['\u1fc6', '\u0345']), ('\u1fc8', &['\u0395', '\u0300']), ('\u1fc9',
- &['\u0388']), ('\u1fca', &['\u0397', '\u0300']), ('\u1fcb', &['\u0389']), ('\u1fcc',
- &['\u0397', '\u0345']), ('\u1fcd', &['\u1fbf', '\u0300']), ('\u1fce', &['\u1fbf',
- '\u0301']), ('\u1fcf', &['\u1fbf', '\u0342']), ('\u1fd0', &['\u03b9', '\u0306']), ('\u1fd1',
- &['\u03b9', '\u0304']), ('\u1fd2', &['\u03ca', '\u0300']), ('\u1fd3', &['\u0390']),
- ('\u1fd6', &['\u03b9', '\u0342']), ('\u1fd7', &['\u03ca', '\u0342']), ('\u1fd8', &['\u0399',
- '\u0306']), ('\u1fd9', &['\u0399', '\u0304']), ('\u1fda', &['\u0399', '\u0300']), ('\u1fdb',
- &['\u038a']), ('\u1fdd', &['\u1ffe', '\u0300']), ('\u1fde', &['\u1ffe', '\u0301']),
- ('\u1fdf', &['\u1ffe', '\u0342']), ('\u1fe0', &['\u03c5', '\u0306']), ('\u1fe1', &['\u03c5',
- '\u0304']), ('\u1fe2', &['\u03cb', '\u0300']), ('\u1fe3', &['\u03b0']), ('\u1fe4',
- &['\u03c1', '\u0313']), ('\u1fe5', &['\u03c1', '\u0314']), ('\u1fe6', &['\u03c5',
- '\u0342']), ('\u1fe7', &['\u03cb', '\u0342']), ('\u1fe8', &['\u03a5', '\u0306']), ('\u1fe9',
- &['\u03a5', '\u0304']), ('\u1fea', &['\u03a5', '\u0300']), ('\u1feb', &['\u038e']),
- ('\u1fec', &['\u03a1', '\u0314']), ('\u1fed', &['\xa8', '\u0300']), ('\u1fee', &['\u0385']),
- ('\u1fef', &['\x60']), ('\u1ff2', &['\u1f7c', '\u0345']), ('\u1ff3', &['\u03c9', '\u0345']),
- ('\u1ff4', &['\u03ce', '\u0345']), ('\u1ff6', &['\u03c9', '\u0342']), ('\u1ff7', &['\u1ff6',
- '\u0345']), ('\u1ff8', &['\u039f', '\u0300']), ('\u1ff9', &['\u038c']), ('\u1ffa',
- &['\u03a9', '\u0300']), ('\u1ffb', &['\u038f']), ('\u1ffc', &['\u03a9', '\u0345']),
- ('\u1ffd', &['\xb4']), ('\u2000', &['\u2002']), ('\u2001', &['\u2003']), ('\u2126',
- &['\u03a9']), ('\u212a', &['\x4b']), ('\u212b', &['\xc5']), ('\u219a', &['\u2190',
- '\u0338']), ('\u219b', &['\u2192', '\u0338']), ('\u21ae', &['\u2194', '\u0338']), ('\u21cd',
- &['\u21d0', '\u0338']), ('\u21ce', &['\u21d4', '\u0338']), ('\u21cf', &['\u21d2',
- '\u0338']), ('\u2204', &['\u2203', '\u0338']), ('\u2209', &['\u2208', '\u0338']), ('\u220c',
- &['\u220b', '\u0338']), ('\u2224', &['\u2223', '\u0338']), ('\u2226', &['\u2225',
- '\u0338']), ('\u2241', &['\u223c', '\u0338']), ('\u2244', &['\u2243', '\u0338']), ('\u2247',
- &['\u2245', '\u0338']), ('\u2249', &['\u2248', '\u0338']), ('\u2260', &['\x3d', '\u0338']),
- ('\u2262', &['\u2261', '\u0338']), ('\u226d', &['\u224d', '\u0338']), ('\u226e', &['\x3c',
- '\u0338']), ('\u226f', &['\x3e', '\u0338']), ('\u2270', &['\u2264', '\u0338']), ('\u2271',
- &['\u2265', '\u0338']), ('\u2274', &['\u2272', '\u0338']), ('\u2275', &['\u2273',
- '\u0338']), ('\u2278', &['\u2276', '\u0338']), ('\u2279', &['\u2277', '\u0338']), ('\u2280',
- &['\u227a', '\u0338']), ('\u2281', &['\u227b', '\u0338']), ('\u2284', &['\u2282',
- '\u0338']), ('\u2285', &['\u2283', '\u0338']), ('\u2288', &['\u2286', '\u0338']), ('\u2289',
- &['\u2287', '\u0338']), ('\u22ac', &['\u22a2', '\u0338']), ('\u22ad', &['\u22a8',
- '\u0338']), ('\u22ae', &['\u22a9', '\u0338']), ('\u22af', &['\u22ab', '\u0338']), ('\u22e0',
- &['\u227c', '\u0338']), ('\u22e1', &['\u227d', '\u0338']), ('\u22e2', &['\u2291',
- '\u0338']), ('\u22e3', &['\u2292', '\u0338']), ('\u22ea', &['\u22b2', '\u0338']), ('\u22eb',
- &['\u22b3', '\u0338']), ('\u22ec', &['\u22b4', '\u0338']), ('\u22ed', &['\u22b5',
- '\u0338']), ('\u2329', &['\u3008']), ('\u232a', &['\u3009']), ('\u2adc', &['\u2add',
- '\u0338']), ('\u304c', &['\u304b', '\u3099']), ('\u304e', &['\u304d', '\u3099']), ('\u3050',
- &['\u304f', '\u3099']), ('\u3052', &['\u3051', '\u3099']), ('\u3054', &['\u3053',
- '\u3099']), ('\u3056', &['\u3055', '\u3099']), ('\u3058', &['\u3057', '\u3099']), ('\u305a',
- &['\u3059', '\u3099']), ('\u305c', &['\u305b', '\u3099']), ('\u305e', &['\u305d',
- '\u3099']), ('\u3060', &['\u305f', '\u3099']), ('\u3062', &['\u3061', '\u3099']), ('\u3065',
- &['\u3064', '\u3099']), ('\u3067', &['\u3066', '\u3099']), ('\u3069', &['\u3068',
- '\u3099']), ('\u3070', &['\u306f', '\u3099']), ('\u3071', &['\u306f', '\u309a']), ('\u3073',
- &['\u3072', '\u3099']), ('\u3074', &['\u3072', '\u309a']), ('\u3076', &['\u3075',
- '\u3099']), ('\u3077', &['\u3075', '\u309a']), ('\u3079', &['\u3078', '\u3099']), ('\u307a',
- &['\u3078', '\u309a']), ('\u307c', &['\u307b', '\u3099']), ('\u307d', &['\u307b',
- '\u309a']), ('\u3094', &['\u3046', '\u3099']), ('\u309e', &['\u309d', '\u3099']), ('\u30ac',
- &['\u30ab', '\u3099']), ('\u30ae', &['\u30ad', '\u3099']), ('\u30b0', &['\u30af',
- '\u3099']), ('\u30b2', &['\u30b1', '\u3099']), ('\u30b4', &['\u30b3', '\u3099']), ('\u30b6',
- &['\u30b5', '\u3099']), ('\u30b8', &['\u30b7', '\u3099']), ('\u30ba', &['\u30b9',
- '\u3099']), ('\u30bc', &['\u30bb', '\u3099']), ('\u30be', &['\u30bd', '\u3099']), ('\u30c0',
- &['\u30bf', '\u3099']), ('\u30c2', &['\u30c1', '\u3099']), ('\u30c5', &['\u30c4',
- '\u3099']), ('\u30c7', &['\u30c6', '\u3099']), ('\u30c9', &['\u30c8', '\u3099']), ('\u30d0',
- &['\u30cf', '\u3099']), ('\u30d1', &['\u30cf', '\u309a']), ('\u30d3', &['\u30d2',
- '\u3099']), ('\u30d4', &['\u30d2', '\u309a']), ('\u30d6', &['\u30d5', '\u3099']), ('\u30d7',
- &['\u30d5', '\u309a']), ('\u30d9', &['\u30d8', '\u3099']), ('\u30da', &['\u30d8',
- '\u309a']), ('\u30dc', &['\u30db', '\u3099']), ('\u30dd', &['\u30db', '\u309a']), ('\u30f4',
- &['\u30a6', '\u3099']), ('\u30f7', &['\u30ef', '\u3099']), ('\u30f8', &['\u30f0',
- '\u3099']), ('\u30f9', &['\u30f1', '\u3099']), ('\u30fa', &['\u30f2', '\u3099']), ('\u30fe',
- &['\u30fd', '\u3099']), ('\uf900', &['\u8c48']), ('\uf901', &['\u66f4']), ('\uf902',
- &['\u8eca']), ('\uf903', &['\u8cc8']), ('\uf904', &['\u6ed1']), ('\uf905', &['\u4e32']),
- ('\uf906', &['\u53e5']), ('\uf907', &['\u9f9c']), ('\uf908', &['\u9f9c']), ('\uf909',
- &['\u5951']), ('\uf90a', &['\u91d1']), ('\uf90b', &['\u5587']), ('\uf90c', &['\u5948']),
- ('\uf90d', &['\u61f6']), ('\uf90e', &['\u7669']), ('\uf90f', &['\u7f85']), ('\uf910',
- &['\u863f']), ('\uf911', &['\u87ba']), ('\uf912', &['\u88f8']), ('\uf913', &['\u908f']),
- ('\uf914', &['\u6a02']), ('\uf915', &['\u6d1b']), ('\uf916', &['\u70d9']), ('\uf917',
- &['\u73de']), ('\uf918', &['\u843d']), ('\uf919', &['\u916a']), ('\uf91a', &['\u99f1']),
- ('\uf91b', &['\u4e82']), ('\uf91c', &['\u5375']), ('\uf91d', &['\u6b04']), ('\uf91e',
- &['\u721b']), ('\uf91f', &['\u862d']), ('\uf920', &['\u9e1e']), ('\uf921', &['\u5d50']),
- ('\uf922', &['\u6feb']), ('\uf923', &['\u85cd']), ('\uf924', &['\u8964']), ('\uf925',
- &['\u62c9']), ('\uf926', &['\u81d8']), ('\uf927', &['\u881f']), ('\uf928', &['\u5eca']),
- ('\uf929', &['\u6717']), ('\uf92a', &['\u6d6a']), ('\uf92b', &['\u72fc']), ('\uf92c',
- &['\u90ce']), ('\uf92d', &['\u4f86']), ('\uf92e', &['\u51b7']), ('\uf92f', &['\u52de']),
- ('\uf930', &['\u64c4']), ('\uf931', &['\u6ad3']), ('\uf932', &['\u7210']), ('\uf933',
- &['\u76e7']), ('\uf934', &['\u8001']), ('\uf935', &['\u8606']), ('\uf936', &['\u865c']),
- ('\uf937', &['\u8def']), ('\uf938', &['\u9732']), ('\uf939', &['\u9b6f']), ('\uf93a',
- &['\u9dfa']), ('\uf93b', &['\u788c']), ('\uf93c', &['\u797f']), ('\uf93d', &['\u7da0']),
- ('\uf93e', &['\u83c9']), ('\uf93f', &['\u9304']), ('\uf940', &['\u9e7f']), ('\uf941',
- &['\u8ad6']), ('\uf942', &['\u58df']), ('\uf943', &['\u5f04']), ('\uf944', &['\u7c60']),
- ('\uf945', &['\u807e']), ('\uf946', &['\u7262']), ('\uf947', &['\u78ca']), ('\uf948',
- &['\u8cc2']), ('\uf949', &['\u96f7']), ('\uf94a', &['\u58d8']), ('\uf94b', &['\u5c62']),
- ('\uf94c', &['\u6a13']), ('\uf94d', &['\u6dda']), ('\uf94e', &['\u6f0f']), ('\uf94f',
- &['\u7d2f']), ('\uf950', &['\u7e37']), ('\uf951', &['\u964b']), ('\uf952', &['\u52d2']),
- ('\uf953', &['\u808b']), ('\uf954', &['\u51dc']), ('\uf955', &['\u51cc']), ('\uf956',
- &['\u7a1c']), ('\uf957', &['\u7dbe']), ('\uf958', &['\u83f1']), ('\uf959', &['\u9675']),
- ('\uf95a', &['\u8b80']), ('\uf95b', &['\u62cf']), ('\uf95c', &['\u6a02']), ('\uf95d',
- &['\u8afe']), ('\uf95e', &['\u4e39']), ('\uf95f', &['\u5be7']), ('\uf960', &['\u6012']),
- ('\uf961', &['\u7387']), ('\uf962', &['\u7570']), ('\uf963', &['\u5317']), ('\uf964',
- &['\u78fb']), ('\uf965', &['\u4fbf']), ('\uf966', &['\u5fa9']), ('\uf967', &['\u4e0d']),
- ('\uf968', &['\u6ccc']), ('\uf969', &['\u6578']), ('\uf96a', &['\u7d22']), ('\uf96b',
- &['\u53c3']), ('\uf96c', &['\u585e']), ('\uf96d', &['\u7701']), ('\uf96e', &['\u8449']),
- ('\uf96f', &['\u8aaa']), ('\uf970', &['\u6bba']), ('\uf971', &['\u8fb0']), ('\uf972',
- &['\u6c88']), ('\uf973', &['\u62fe']), ('\uf974', &['\u82e5']), ('\uf975', &['\u63a0']),
- ('\uf976', &['\u7565']), ('\uf977', &['\u4eae']), ('\uf978', &['\u5169']), ('\uf979',
- &['\u51c9']), ('\uf97a', &['\u6881']), ('\uf97b', &['\u7ce7']), ('\uf97c', &['\u826f']),
- ('\uf97d', &['\u8ad2']), ('\uf97e', &['\u91cf']), ('\uf97f', &['\u52f5']), ('\uf980',
- &['\u5442']), ('\uf981', &['\u5973']), ('\uf982', &['\u5eec']), ('\uf983', &['\u65c5']),
- ('\uf984', &['\u6ffe']), ('\uf985', &['\u792a']), ('\uf986', &['\u95ad']), ('\uf987',
- &['\u9a6a']), ('\uf988', &['\u9e97']), ('\uf989', &['\u9ece']), ('\uf98a', &['\u529b']),
- ('\uf98b', &['\u66c6']), ('\uf98c', &['\u6b77']), ('\uf98d', &['\u8f62']), ('\uf98e',
- &['\u5e74']), ('\uf98f', &['\u6190']), ('\uf990', &['\u6200']), ('\uf991', &['\u649a']),
- ('\uf992', &['\u6f23']), ('\uf993', &['\u7149']), ('\uf994', &['\u7489']), ('\uf995',
- &['\u79ca']), ('\uf996', &['\u7df4']), ('\uf997', &['\u806f']), ('\uf998', &['\u8f26']),
- ('\uf999', &['\u84ee']), ('\uf99a', &['\u9023']), ('\uf99b', &['\u934a']), ('\uf99c',
- &['\u5217']), ('\uf99d', &['\u52a3']), ('\uf99e', &['\u54bd']), ('\uf99f', &['\u70c8']),
- ('\uf9a0', &['\u88c2']), ('\uf9a1', &['\u8aaa']), ('\uf9a2', &['\u5ec9']), ('\uf9a3',
- &['\u5ff5']), ('\uf9a4', &['\u637b']), ('\uf9a5', &['\u6bae']), ('\uf9a6', &['\u7c3e']),
- ('\uf9a7', &['\u7375']), ('\uf9a8', &['\u4ee4']), ('\uf9a9', &['\u56f9']), ('\uf9aa',
- &['\u5be7']), ('\uf9ab', &['\u5dba']), ('\uf9ac', &['\u601c']), ('\uf9ad', &['\u73b2']),
- ('\uf9ae', &['\u7469']), ('\uf9af', &['\u7f9a']), ('\uf9b0', &['\u8046']), ('\uf9b1',
- &['\u9234']), ('\uf9b2', &['\u96f6']), ('\uf9b3', &['\u9748']), ('\uf9b4', &['\u9818']),
- ('\uf9b5', &['\u4f8b']), ('\uf9b6', &['\u79ae']), ('\uf9b7', &['\u91b4']), ('\uf9b8',
- &['\u96b8']), ('\uf9b9', &['\u60e1']), ('\uf9ba', &['\u4e86']), ('\uf9bb', &['\u50da']),
- ('\uf9bc', &['\u5bee']), ('\uf9bd', &['\u5c3f']), ('\uf9be', &['\u6599']), ('\uf9bf',
- &['\u6a02']), ('\uf9c0', &['\u71ce']), ('\uf9c1', &['\u7642']), ('\uf9c2', &['\u84fc']),
- ('\uf9c3', &['\u907c']), ('\uf9c4', &['\u9f8d']), ('\uf9c5', &['\u6688']), ('\uf9c6',
- &['\u962e']), ('\uf9c7', &['\u5289']), ('\uf9c8', &['\u677b']), ('\uf9c9', &['\u67f3']),
- ('\uf9ca', &['\u6d41']), ('\uf9cb', &['\u6e9c']), ('\uf9cc', &['\u7409']), ('\uf9cd',
- &['\u7559']), ('\uf9ce', &['\u786b']), ('\uf9cf', &['\u7d10']), ('\uf9d0', &['\u985e']),
- ('\uf9d1', &['\u516d']), ('\uf9d2', &['\u622e']), ('\uf9d3', &['\u9678']), ('\uf9d4',
- &['\u502b']), ('\uf9d5', &['\u5d19']), ('\uf9d6', &['\u6dea']), ('\uf9d7', &['\u8f2a']),
- ('\uf9d8', &['\u5f8b']), ('\uf9d9', &['\u6144']), ('\uf9da', &['\u6817']), ('\uf9db',
- &['\u7387']), ('\uf9dc', &['\u9686']), ('\uf9dd', &['\u5229']), ('\uf9de', &['\u540f']),
- ('\uf9df', &['\u5c65']), ('\uf9e0', &['\u6613']), ('\uf9e1', &['\u674e']), ('\uf9e2',
- &['\u68a8']), ('\uf9e3', &['\u6ce5']), ('\uf9e4', &['\u7406']), ('\uf9e5', &['\u75e2']),
- ('\uf9e6', &['\u7f79']), ('\uf9e7', &['\u88cf']), ('\uf9e8', &['\u88e1']), ('\uf9e9',
- &['\u91cc']), ('\uf9ea', &['\u96e2']), ('\uf9eb', &['\u533f']), ('\uf9ec', &['\u6eba']),
- ('\uf9ed', &['\u541d']), ('\uf9ee', &['\u71d0']), ('\uf9ef', &['\u7498']), ('\uf9f0',
- &['\u85fa']), ('\uf9f1', &['\u96a3']), ('\uf9f2', &['\u9c57']), ('\uf9f3', &['\u9e9f']),
- ('\uf9f4', &['\u6797']), ('\uf9f5', &['\u6dcb']), ('\uf9f6', &['\u81e8']), ('\uf9f7',
- &['\u7acb']), ('\uf9f8', &['\u7b20']), ('\uf9f9', &['\u7c92']), ('\uf9fa', &['\u72c0']),
- ('\uf9fb', &['\u7099']), ('\uf9fc', &['\u8b58']), ('\uf9fd', &['\u4ec0']), ('\uf9fe',
- &['\u8336']), ('\uf9ff', &['\u523a']), ('\ufa00', &['\u5207']), ('\ufa01', &['\u5ea6']),
- ('\ufa02', &['\u62d3']), ('\ufa03', &['\u7cd6']), ('\ufa04', &['\u5b85']), ('\ufa05',
- &['\u6d1e']), ('\ufa06', &['\u66b4']), ('\ufa07', &['\u8f3b']), ('\ufa08', &['\u884c']),
- ('\ufa09', &['\u964d']), ('\ufa0a', &['\u898b']), ('\ufa0b', &['\u5ed3']), ('\ufa0c',
- &['\u5140']), ('\ufa0d', &['\u55c0']), ('\ufa10', &['\u585a']), ('\ufa12', &['\u6674']),
- ('\ufa15', &['\u51de']), ('\ufa16', &['\u732a']), ('\ufa17', &['\u76ca']), ('\ufa18',
- &['\u793c']), ('\ufa19', &['\u795e']), ('\ufa1a', &['\u7965']), ('\ufa1b', &['\u798f']),
- ('\ufa1c', &['\u9756']), ('\ufa1d', &['\u7cbe']), ('\ufa1e', &['\u7fbd']), ('\ufa20',
- &['\u8612']), ('\ufa22', &['\u8af8']), ('\ufa25', &['\u9038']), ('\ufa26', &['\u90fd']),
- ('\ufa2a', &['\u98ef']), ('\ufa2b', &['\u98fc']), ('\ufa2c', &['\u9928']), ('\ufa2d',
- &['\u9db4']), ('\ufa2e', &['\u90de']), ('\ufa2f', &['\u96b7']), ('\ufa30', &['\u4fae']),
- ('\ufa31', &['\u50e7']), ('\ufa32', &['\u514d']), ('\ufa33', &['\u52c9']), ('\ufa34',
- &['\u52e4']), ('\ufa35', &['\u5351']), ('\ufa36', &['\u559d']), ('\ufa37', &['\u5606']),
- ('\ufa38', &['\u5668']), ('\ufa39', &['\u5840']), ('\ufa3a', &['\u58a8']), ('\ufa3b',
- &['\u5c64']), ('\ufa3c', &['\u5c6e']), ('\ufa3d', &['\u6094']), ('\ufa3e', &['\u6168']),
- ('\ufa3f', &['\u618e']), ('\ufa40', &['\u61f2']), ('\ufa41', &['\u654f']), ('\ufa42',
- &['\u65e2']), ('\ufa43', &['\u6691']), ('\ufa44', &['\u6885']), ('\ufa45', &['\u6d77']),
- ('\ufa46', &['\u6e1a']), ('\ufa47', &['\u6f22']), ('\ufa48', &['\u716e']), ('\ufa49',
- &['\u722b']), ('\ufa4a', &['\u7422']), ('\ufa4b', &['\u7891']), ('\ufa4c', &['\u793e']),
- ('\ufa4d', &['\u7949']), ('\ufa4e', &['\u7948']), ('\ufa4f', &['\u7950']), ('\ufa50',
- &['\u7956']), ('\ufa51', &['\u795d']), ('\ufa52', &['\u798d']), ('\ufa53', &['\u798e']),
- ('\ufa54', &['\u7a40']), ('\ufa55', &['\u7a81']), ('\ufa56', &['\u7bc0']), ('\ufa57',
- &['\u7df4']), ('\ufa58', &['\u7e09']), ('\ufa59', &['\u7e41']), ('\ufa5a', &['\u7f72']),
- ('\ufa5b', &['\u8005']), ('\ufa5c', &['\u81ed']), ('\ufa5d', &['\u8279']), ('\ufa5e',
- &['\u8279']), ('\ufa5f', &['\u8457']), ('\ufa60', &['\u8910']), ('\ufa61', &['\u8996']),
- ('\ufa62', &['\u8b01']), ('\ufa63', &['\u8b39']), ('\ufa64', &['\u8cd3']), ('\ufa65',
- &['\u8d08']), ('\ufa66', &['\u8fb6']), ('\ufa67', &['\u9038']), ('\ufa68', &['\u96e3']),
- ('\ufa69', &['\u97ff']), ('\ufa6a', &['\u983b']), ('\ufa6b', &['\u6075']), ('\ufa6c',
- &['\U000242ee']), ('\ufa6d', &['\u8218']), ('\ufa70', &['\u4e26']), ('\ufa71', &['\u51b5']),
- ('\ufa72', &['\u5168']), ('\ufa73', &['\u4f80']), ('\ufa74', &['\u5145']), ('\ufa75',
- &['\u5180']), ('\ufa76', &['\u52c7']), ('\ufa77', &['\u52fa']), ('\ufa78', &['\u559d']),
- ('\ufa79', &['\u5555']), ('\ufa7a', &['\u5599']), ('\ufa7b', &['\u55e2']), ('\ufa7c',
- &['\u585a']), ('\ufa7d', &['\u58b3']), ('\ufa7e', &['\u5944']), ('\ufa7f', &['\u5954']),
- ('\ufa80', &['\u5a62']), ('\ufa81', &['\u5b28']), ('\ufa82', &['\u5ed2']), ('\ufa83',
- &['\u5ed9']), ('\ufa84', &['\u5f69']), ('\ufa85', &['\u5fad']), ('\ufa86', &['\u60d8']),
- ('\ufa87', &['\u614e']), ('\ufa88', &['\u6108']), ('\ufa89', &['\u618e']), ('\ufa8a',
- &['\u6160']), ('\ufa8b', &['\u61f2']), ('\ufa8c', &['\u6234']), ('\ufa8d', &['\u63c4']),
- ('\ufa8e', &['\u641c']), ('\ufa8f', &['\u6452']), ('\ufa90', &['\u6556']), ('\ufa91',
- &['\u6674']), ('\ufa92', &['\u6717']), ('\ufa93', &['\u671b']), ('\ufa94', &['\u6756']),
- ('\ufa95', &['\u6b79']), ('\ufa96', &['\u6bba']), ('\ufa97', &['\u6d41']), ('\ufa98',
- &['\u6edb']), ('\ufa99', &['\u6ecb']), ('\ufa9a', &['\u6f22']), ('\ufa9b', &['\u701e']),
- ('\ufa9c', &['\u716e']), ('\ufa9d', &['\u77a7']), ('\ufa9e', &['\u7235']), ('\ufa9f',
- &['\u72af']), ('\ufaa0', &['\u732a']), ('\ufaa1', &['\u7471']), ('\ufaa2', &['\u7506']),
- ('\ufaa3', &['\u753b']), ('\ufaa4', &['\u761d']), ('\ufaa5', &['\u761f']), ('\ufaa6',
- &['\u76ca']), ('\ufaa7', &['\u76db']), ('\ufaa8', &['\u76f4']), ('\ufaa9', &['\u774a']),
- ('\ufaaa', &['\u7740']), ('\ufaab', &['\u78cc']), ('\ufaac', &['\u7ab1']), ('\ufaad',
- &['\u7bc0']), ('\ufaae', &['\u7c7b']), ('\ufaaf', &['\u7d5b']), ('\ufab0', &['\u7df4']),
- ('\ufab1', &['\u7f3e']), ('\ufab2', &['\u8005']), ('\ufab3', &['\u8352']), ('\ufab4',
- &['\u83ef']), ('\ufab5', &['\u8779']), ('\ufab6', &['\u8941']), ('\ufab7', &['\u8986']),
- ('\ufab8', &['\u8996']), ('\ufab9', &['\u8abf']), ('\ufaba', &['\u8af8']), ('\ufabb',
- &['\u8acb']), ('\ufabc', &['\u8b01']), ('\ufabd', &['\u8afe']), ('\ufabe', &['\u8aed']),
- ('\ufabf', &['\u8b39']), ('\ufac0', &['\u8b8a']), ('\ufac1', &['\u8d08']), ('\ufac2',
- &['\u8f38']), ('\ufac3', &['\u9072']), ('\ufac4', &['\u9199']), ('\ufac5', &['\u9276']),
- ('\ufac6', &['\u967c']), ('\ufac7', &['\u96e3']), ('\ufac8', &['\u9756']), ('\ufac9',
- &['\u97db']), ('\ufaca', &['\u97ff']), ('\ufacb', &['\u980b']), ('\ufacc', &['\u983b']),
- ('\ufacd', &['\u9b12']), ('\uface', &['\u9f9c']), ('\ufacf', &['\U0002284a']), ('\ufad0',
- &['\U00022844']), ('\ufad1', &['\U000233d5']), ('\ufad2', &['\u3b9d']), ('\ufad3',
- &['\u4018']), ('\ufad4', &['\u4039']), ('\ufad5', &['\U00025249']), ('\ufad6',
- &['\U00025cd0']), ('\ufad7', &['\U00027ed3']), ('\ufad8', &['\u9f43']), ('\ufad9',
- &['\u9f8e']), ('\ufb1d', &['\u05d9', '\u05b4']), ('\ufb1f', &['\u05f2', '\u05b7']),
- ('\ufb2a', &['\u05e9', '\u05c1']), ('\ufb2b', &['\u05e9', '\u05c2']), ('\ufb2c', &['\ufb49',
- '\u05c1']), ('\ufb2d', &['\ufb49', '\u05c2']), ('\ufb2e', &['\u05d0', '\u05b7']), ('\ufb2f',
- &['\u05d0', '\u05b8']), ('\ufb30', &['\u05d0', '\u05bc']), ('\ufb31', &['\u05d1',
- '\u05bc']), ('\ufb32', &['\u05d2', '\u05bc']), ('\ufb33', &['\u05d3', '\u05bc']), ('\ufb34',
- &['\u05d4', '\u05bc']), ('\ufb35', &['\u05d5', '\u05bc']), ('\ufb36', &['\u05d6',
- '\u05bc']), ('\ufb38', &['\u05d8', '\u05bc']), ('\ufb39', &['\u05d9', '\u05bc']), ('\ufb3a',
- &['\u05da', '\u05bc']), ('\ufb3b', &['\u05db', '\u05bc']), ('\ufb3c', &['\u05dc',
- '\u05bc']), ('\ufb3e', &['\u05de', '\u05bc']), ('\ufb40', &['\u05e0', '\u05bc']), ('\ufb41',
- &['\u05e1', '\u05bc']), ('\ufb43', &['\u05e3', '\u05bc']), ('\ufb44', &['\u05e4',
- '\u05bc']), ('\ufb46', &['\u05e6', '\u05bc']), ('\ufb47', &['\u05e7', '\u05bc']), ('\ufb48',
- &['\u05e8', '\u05bc']), ('\ufb49', &['\u05e9', '\u05bc']), ('\ufb4a', &['\u05ea',
- '\u05bc']), ('\ufb4b', &['\u05d5', '\u05b9']), ('\ufb4c', &['\u05d1', '\u05bf']), ('\ufb4d',
- &['\u05db', '\u05bf']), ('\ufb4e', &['\u05e4', '\u05bf']), ('\U0001109a', &['\U00011099',
- '\U000110ba']), ('\U0001109c', &['\U0001109b', '\U000110ba']), ('\U000110ab',
- &['\U000110a5', '\U000110ba']), ('\U0001112e', &['\U00011131', '\U00011127']),
- ('\U0001112f', &['\U00011132', '\U00011127']), ('\U0001d15e', &['\U0001d157',
- '\U0001d165']), ('\U0001d15f', &['\U0001d158', '\U0001d165']), ('\U0001d160',
- &['\U0001d15f', '\U0001d16e']), ('\U0001d161', &['\U0001d15f', '\U0001d16f']),
- ('\U0001d162', &['\U0001d15f', '\U0001d170']), ('\U0001d163', &['\U0001d15f',
- '\U0001d171']), ('\U0001d164', &['\U0001d15f', '\U0001d172']), ('\U0001d1bb',
- &['\U0001d1b9', '\U0001d165']), ('\U0001d1bc', &['\U0001d1ba', '\U0001d165']),
- ('\U0001d1bd', &['\U0001d1bb', '\U0001d16e']), ('\U0001d1be', &['\U0001d1bc',
- '\U0001d16e']), ('\U0001d1bf', &['\U0001d1bb', '\U0001d16f']), ('\U0001d1c0',
- &['\U0001d1bc', '\U0001d16f']), ('\U0002f800', &['\u4e3d']), ('\U0002f801', &['\u4e38']),
- ('\U0002f802', &['\u4e41']), ('\U0002f803', &['\U00020122']), ('\U0002f804', &['\u4f60']),
- ('\U0002f805', &['\u4fae']), ('\U0002f806', &['\u4fbb']), ('\U0002f807', &['\u5002']),
- ('\U0002f808', &['\u507a']), ('\U0002f809', &['\u5099']), ('\U0002f80a', &['\u50e7']),
- ('\U0002f80b', &['\u50cf']), ('\U0002f80c', &['\u349e']), ('\U0002f80d', &['\U0002063a']),
- ('\U0002f80e', &['\u514d']), ('\U0002f80f', &['\u5154']), ('\U0002f810', &['\u5164']),
- ('\U0002f811', &['\u5177']), ('\U0002f812', &['\U0002051c']), ('\U0002f813', &['\u34b9']),
- ('\U0002f814', &['\u5167']), ('\U0002f815', &['\u518d']), ('\U0002f816', &['\U0002054b']),
- ('\U0002f817', &['\u5197']), ('\U0002f818', &['\u51a4']), ('\U0002f819', &['\u4ecc']),
- ('\U0002f81a', &['\u51ac']), ('\U0002f81b', &['\u51b5']), ('\U0002f81c', &['\U000291df']),
- ('\U0002f81d', &['\u51f5']), ('\U0002f81e', &['\u5203']), ('\U0002f81f', &['\u34df']),
- ('\U0002f820', &['\u523b']), ('\U0002f821', &['\u5246']), ('\U0002f822', &['\u5272']),
- ('\U0002f823', &['\u5277']), ('\U0002f824', &['\u3515']), ('\U0002f825', &['\u52c7']),
- ('\U0002f826', &['\u52c9']), ('\U0002f827', &['\u52e4']), ('\U0002f828', &['\u52fa']),
- ('\U0002f829', &['\u5305']), ('\U0002f82a', &['\u5306']), ('\U0002f82b', &['\u5317']),
- ('\U0002f82c', &['\u5349']), ('\U0002f82d', &['\u5351']), ('\U0002f82e', &['\u535a']),
- ('\U0002f82f', &['\u5373']), ('\U0002f830', &['\u537d']), ('\U0002f831', &['\u537f']),
- ('\U0002f832', &['\u537f']), ('\U0002f833', &['\u537f']), ('\U0002f834', &['\U00020a2c']),
- ('\U0002f835', &['\u7070']), ('\U0002f836', &['\u53ca']), ('\U0002f837', &['\u53df']),
- ('\U0002f838', &['\U00020b63']), ('\U0002f839', &['\u53eb']), ('\U0002f83a', &['\u53f1']),
- ('\U0002f83b', &['\u5406']), ('\U0002f83c', &['\u549e']), ('\U0002f83d', &['\u5438']),
- ('\U0002f83e', &['\u5448']), ('\U0002f83f', &['\u5468']), ('\U0002f840', &['\u54a2']),
- ('\U0002f841', &['\u54f6']), ('\U0002f842', &['\u5510']), ('\U0002f843', &['\u5553']),
- ('\U0002f844', &['\u5563']), ('\U0002f845', &['\u5584']), ('\U0002f846', &['\u5584']),
- ('\U0002f847', &['\u5599']), ('\U0002f848', &['\u55ab']), ('\U0002f849', &['\u55b3']),
- ('\U0002f84a', &['\u55c2']), ('\U0002f84b', &['\u5716']), ('\U0002f84c', &['\u5606']),
- ('\U0002f84d', &['\u5717']), ('\U0002f84e', &['\u5651']), ('\U0002f84f', &['\u5674']),
- ('\U0002f850', &['\u5207']), ('\U0002f851', &['\u58ee']), ('\U0002f852', &['\u57ce']),
- ('\U0002f853', &['\u57f4']), ('\U0002f854', &['\u580d']), ('\U0002f855', &['\u578b']),
- ('\U0002f856', &['\u5832']), ('\U0002f857', &['\u5831']), ('\U0002f858', &['\u58ac']),
- ('\U0002f859', &['\U000214e4']), ('\U0002f85a', &['\u58f2']), ('\U0002f85b', &['\u58f7']),
- ('\U0002f85c', &['\u5906']), ('\U0002f85d', &['\u591a']), ('\U0002f85e', &['\u5922']),
- ('\U0002f85f', &['\u5962']), ('\U0002f860', &['\U000216a8']), ('\U0002f861',
- &['\U000216ea']), ('\U0002f862', &['\u59ec']), ('\U0002f863', &['\u5a1b']), ('\U0002f864',
- &['\u5a27']), ('\U0002f865', &['\u59d8']), ('\U0002f866', &['\u5a66']), ('\U0002f867',
- &['\u36ee']), ('\U0002f868', &['\u36fc']), ('\U0002f869', &['\u5b08']), ('\U0002f86a',
- &['\u5b3e']), ('\U0002f86b', &['\u5b3e']), ('\U0002f86c', &['\U000219c8']), ('\U0002f86d',
- &['\u5bc3']), ('\U0002f86e', &['\u5bd8']), ('\U0002f86f', &['\u5be7']), ('\U0002f870',
- &['\u5bf3']), ('\U0002f871', &['\U00021b18']), ('\U0002f872', &['\u5bff']), ('\U0002f873',
- &['\u5c06']), ('\U0002f874', &['\u5f53']), ('\U0002f875', &['\u5c22']), ('\U0002f876',
- &['\u3781']), ('\U0002f877', &['\u5c60']), ('\U0002f878', &['\u5c6e']), ('\U0002f879',
- &['\u5cc0']), ('\U0002f87a', &['\u5c8d']), ('\U0002f87b', &['\U00021de4']), ('\U0002f87c',
- &['\u5d43']), ('\U0002f87d', &['\U00021de6']), ('\U0002f87e', &['\u5d6e']), ('\U0002f87f',
- &['\u5d6b']), ('\U0002f880', &['\u5d7c']), ('\U0002f881', &['\u5de1']), ('\U0002f882',
- &['\u5de2']), ('\U0002f883', &['\u382f']), ('\U0002f884', &['\u5dfd']), ('\U0002f885',
- &['\u5e28']), ('\U0002f886', &['\u5e3d']), ('\U0002f887', &['\u5e69']), ('\U0002f888',
- &['\u3862']), ('\U0002f889', &['\U00022183']), ('\U0002f88a', &['\u387c']), ('\U0002f88b',
- &['\u5eb0']), ('\U0002f88c', &['\u5eb3']), ('\U0002f88d', &['\u5eb6']), ('\U0002f88e',
- &['\u5eca']), ('\U0002f88f', &['\U0002a392']), ('\U0002f890', &['\u5efe']), ('\U0002f891',
- &['\U00022331']), ('\U0002f892', &['\U00022331']), ('\U0002f893', &['\u8201']),
- ('\U0002f894', &['\u5f22']), ('\U0002f895', &['\u5f22']), ('\U0002f896', &['\u38c7']),
- ('\U0002f897', &['\U000232b8']), ('\U0002f898', &['\U000261da']), ('\U0002f899',
- &['\u5f62']), ('\U0002f89a', &['\u5f6b']), ('\U0002f89b', &['\u38e3']), ('\U0002f89c',
- &['\u5f9a']), ('\U0002f89d', &['\u5fcd']), ('\U0002f89e', &['\u5fd7']), ('\U0002f89f',
- &['\u5ff9']), ('\U0002f8a0', &['\u6081']), ('\U0002f8a1', &['\u393a']), ('\U0002f8a2',
- &['\u391c']), ('\U0002f8a3', &['\u6094']), ('\U0002f8a4', &['\U000226d4']), ('\U0002f8a5',
- &['\u60c7']), ('\U0002f8a6', &['\u6148']), ('\U0002f8a7', &['\u614c']), ('\U0002f8a8',
- &['\u614e']), ('\U0002f8a9', &['\u614c']), ('\U0002f8aa', &['\u617a']), ('\U0002f8ab',
- &['\u618e']), ('\U0002f8ac', &['\u61b2']), ('\U0002f8ad', &['\u61a4']), ('\U0002f8ae',
- &['\u61af']), ('\U0002f8af', &['\u61de']), ('\U0002f8b0', &['\u61f2']), ('\U0002f8b1',
- &['\u61f6']), ('\U0002f8b2', &['\u6210']), ('\U0002f8b3', &['\u621b']), ('\U0002f8b4',
- &['\u625d']), ('\U0002f8b5', &['\u62b1']), ('\U0002f8b6', &['\u62d4']), ('\U0002f8b7',
- &['\u6350']), ('\U0002f8b8', &['\U00022b0c']), ('\U0002f8b9', &['\u633d']), ('\U0002f8ba',
- &['\u62fc']), ('\U0002f8bb', &['\u6368']), ('\U0002f8bc', &['\u6383']), ('\U0002f8bd',
- &['\u63e4']), ('\U0002f8be', &['\U00022bf1']), ('\U0002f8bf', &['\u6422']), ('\U0002f8c0',
- &['\u63c5']), ('\U0002f8c1', &['\u63a9']), ('\U0002f8c2', &['\u3a2e']), ('\U0002f8c3',
- &['\u6469']), ('\U0002f8c4', &['\u647e']), ('\U0002f8c5', &['\u649d']), ('\U0002f8c6',
- &['\u6477']), ('\U0002f8c7', &['\u3a6c']), ('\U0002f8c8', &['\u654f']), ('\U0002f8c9',
- &['\u656c']), ('\U0002f8ca', &['\U0002300a']), ('\U0002f8cb', &['\u65e3']), ('\U0002f8cc',
- &['\u66f8']), ('\U0002f8cd', &['\u6649']), ('\U0002f8ce', &['\u3b19']), ('\U0002f8cf',
- &['\u6691']), ('\U0002f8d0', &['\u3b08']), ('\U0002f8d1', &['\u3ae4']), ('\U0002f8d2',
- &['\u5192']), ('\U0002f8d3', &['\u5195']), ('\U0002f8d4', &['\u6700']), ('\U0002f8d5',
- &['\u669c']), ('\U0002f8d6', &['\u80ad']), ('\U0002f8d7', &['\u43d9']), ('\U0002f8d8',
- &['\u6717']), ('\U0002f8d9', &['\u671b']), ('\U0002f8da', &['\u6721']), ('\U0002f8db',
- &['\u675e']), ('\U0002f8dc', &['\u6753']), ('\U0002f8dd', &['\U000233c3']), ('\U0002f8de',
- &['\u3b49']), ('\U0002f8df', &['\u67fa']), ('\U0002f8e0', &['\u6785']), ('\U0002f8e1',
- &['\u6852']), ('\U0002f8e2', &['\u6885']), ('\U0002f8e3', &['\U0002346d']), ('\U0002f8e4',
- &['\u688e']), ('\U0002f8e5', &['\u681f']), ('\U0002f8e6', &['\u6914']), ('\U0002f8e7',
- &['\u3b9d']), ('\U0002f8e8', &['\u6942']), ('\U0002f8e9', &['\u69a3']), ('\U0002f8ea',
- &['\u69ea']), ('\U0002f8eb', &['\u6aa8']), ('\U0002f8ec', &['\U000236a3']), ('\U0002f8ed',
- &['\u6adb']), ('\U0002f8ee', &['\u3c18']), ('\U0002f8ef', &['\u6b21']), ('\U0002f8f0',
- &['\U000238a7']), ('\U0002f8f1', &['\u6b54']), ('\U0002f8f2', &['\u3c4e']), ('\U0002f8f3',
- &['\u6b72']), ('\U0002f8f4', &['\u6b9f']), ('\U0002f8f5', &['\u6bba']), ('\U0002f8f6',
- &['\u6bbb']), ('\U0002f8f7', &['\U00023a8d']), ('\U0002f8f8', &['\U00021d0b']),
- ('\U0002f8f9', &['\U00023afa']), ('\U0002f8fa', &['\u6c4e']), ('\U0002f8fb',
- &['\U00023cbc']), ('\U0002f8fc', &['\u6cbf']), ('\U0002f8fd', &['\u6ccd']), ('\U0002f8fe',
- &['\u6c67']), ('\U0002f8ff', &['\u6d16']), ('\U0002f900', &['\u6d3e']), ('\U0002f901',
- &['\u6d77']), ('\U0002f902', &['\u6d41']), ('\U0002f903', &['\u6d69']), ('\U0002f904',
- &['\u6d78']), ('\U0002f905', &['\u6d85']), ('\U0002f906', &['\U00023d1e']), ('\U0002f907',
- &['\u6d34']), ('\U0002f908', &['\u6e2f']), ('\U0002f909', &['\u6e6e']), ('\U0002f90a',
- &['\u3d33']), ('\U0002f90b', &['\u6ecb']), ('\U0002f90c', &['\u6ec7']), ('\U0002f90d',
- &['\U00023ed1']), ('\U0002f90e', &['\u6df9']), ('\U0002f90f', &['\u6f6e']), ('\U0002f910',
- &['\U00023f5e']), ('\U0002f911', &['\U00023f8e']), ('\U0002f912', &['\u6fc6']),
- ('\U0002f913', &['\u7039']), ('\U0002f914', &['\u701e']), ('\U0002f915', &['\u701b']),
- ('\U0002f916', &['\u3d96']), ('\U0002f917', &['\u704a']), ('\U0002f918', &['\u707d']),
- ('\U0002f919', &['\u7077']), ('\U0002f91a', &['\u70ad']), ('\U0002f91b', &['\U00020525']),
- ('\U0002f91c', &['\u7145']), ('\U0002f91d', &['\U00024263']), ('\U0002f91e', &['\u719c']),
- ('\U0002f91f', &['\U000243ab']), ('\U0002f920', &['\u7228']), ('\U0002f921', &['\u7235']),
- ('\U0002f922', &['\u7250']), ('\U0002f923', &['\U00024608']), ('\U0002f924', &['\u7280']),
- ('\U0002f925', &['\u7295']), ('\U0002f926', &['\U00024735']), ('\U0002f927',
- &['\U00024814']), ('\U0002f928', &['\u737a']), ('\U0002f929', &['\u738b']), ('\U0002f92a',
- &['\u3eac']), ('\U0002f92b', &['\u73a5']), ('\U0002f92c', &['\u3eb8']), ('\U0002f92d',
- &['\u3eb8']), ('\U0002f92e', &['\u7447']), ('\U0002f92f', &['\u745c']), ('\U0002f930',
- &['\u7471']), ('\U0002f931', &['\u7485']), ('\U0002f932', &['\u74ca']), ('\U0002f933',
- &['\u3f1b']), ('\U0002f934', &['\u7524']), ('\U0002f935', &['\U00024c36']), ('\U0002f936',
- &['\u753e']), ('\U0002f937', &['\U00024c92']), ('\U0002f938', &['\u7570']), ('\U0002f939',
- &['\U0002219f']), ('\U0002f93a', &['\u7610']), ('\U0002f93b', &['\U00024fa1']),
- ('\U0002f93c', &['\U00024fb8']), ('\U0002f93d', &['\U00025044']), ('\U0002f93e',
- &['\u3ffc']), ('\U0002f93f', &['\u4008']), ('\U0002f940', &['\u76f4']), ('\U0002f941',
- &['\U000250f3']), ('\U0002f942', &['\U000250f2']), ('\U0002f943', &['\U00025119']),
- ('\U0002f944', &['\U00025133']), ('\U0002f945', &['\u771e']), ('\U0002f946', &['\u771f']),
- ('\U0002f947', &['\u771f']), ('\U0002f948', &['\u774a']), ('\U0002f949', &['\u4039']),
- ('\U0002f94a', &['\u778b']), ('\U0002f94b', &['\u4046']), ('\U0002f94c', &['\u4096']),
- ('\U0002f94d', &['\U0002541d']), ('\U0002f94e', &['\u784e']), ('\U0002f94f', &['\u788c']),
- ('\U0002f950', &['\u78cc']), ('\U0002f951', &['\u40e3']), ('\U0002f952', &['\U00025626']),
- ('\U0002f953', &['\u7956']), ('\U0002f954', &['\U0002569a']), ('\U0002f955',
- &['\U000256c5']), ('\U0002f956', &['\u798f']), ('\U0002f957', &['\u79eb']), ('\U0002f958',
- &['\u412f']), ('\U0002f959', &['\u7a40']), ('\U0002f95a', &['\u7a4a']), ('\U0002f95b',
- &['\u7a4f']), ('\U0002f95c', &['\U0002597c']), ('\U0002f95d', &['\U00025aa7']),
- ('\U0002f95e', &['\U00025aa7']), ('\U0002f95f', &['\u7aee']), ('\U0002f960', &['\u4202']),
- ('\U0002f961', &['\U00025bab']), ('\U0002f962', &['\u7bc6']), ('\U0002f963', &['\u7bc9']),
- ('\U0002f964', &['\u4227']), ('\U0002f965', &['\U00025c80']), ('\U0002f966', &['\u7cd2']),
- ('\U0002f967', &['\u42a0']), ('\U0002f968', &['\u7ce8']), ('\U0002f969', &['\u7ce3']),
- ('\U0002f96a', &['\u7d00']), ('\U0002f96b', &['\U00025f86']), ('\U0002f96c', &['\u7d63']),
- ('\U0002f96d', &['\u4301']), ('\U0002f96e', &['\u7dc7']), ('\U0002f96f', &['\u7e02']),
- ('\U0002f970', &['\u7e45']), ('\U0002f971', &['\u4334']), ('\U0002f972', &['\U00026228']),
- ('\U0002f973', &['\U00026247']), ('\U0002f974', &['\u4359']), ('\U0002f975',
- &['\U000262d9']), ('\U0002f976', &['\u7f7a']), ('\U0002f977', &['\U0002633e']),
- ('\U0002f978', &['\u7f95']), ('\U0002f979', &['\u7ffa']), ('\U0002f97a', &['\u8005']),
- ('\U0002f97b', &['\U000264da']), ('\U0002f97c', &['\U00026523']), ('\U0002f97d',
- &['\u8060']), ('\U0002f97e', &['\U000265a8']), ('\U0002f97f', &['\u8070']), ('\U0002f980',
- &['\U0002335f']), ('\U0002f981', &['\u43d5']), ('\U0002f982', &['\u80b2']), ('\U0002f983',
- &['\u8103']), ('\U0002f984', &['\u440b']), ('\U0002f985', &['\u813e']), ('\U0002f986',
- &['\u5ab5']), ('\U0002f987', &['\U000267a7']), ('\U0002f988', &['\U000267b5']),
- ('\U0002f989', &['\U00023393']), ('\U0002f98a', &['\U0002339c']), ('\U0002f98b',
- &['\u8201']), ('\U0002f98c', &['\u8204']), ('\U0002f98d', &['\u8f9e']), ('\U0002f98e',
- &['\u446b']), ('\U0002f98f', &['\u8291']), ('\U0002f990', &['\u828b']), ('\U0002f991',
- &['\u829d']), ('\U0002f992', &['\u52b3']), ('\U0002f993', &['\u82b1']), ('\U0002f994',
- &['\u82b3']), ('\U0002f995', &['\u82bd']), ('\U0002f996', &['\u82e6']), ('\U0002f997',
- &['\U00026b3c']), ('\U0002f998', &['\u82e5']), ('\U0002f999', &['\u831d']), ('\U0002f99a',
- &['\u8363']), ('\U0002f99b', &['\u83ad']), ('\U0002f99c', &['\u8323']), ('\U0002f99d',
- &['\u83bd']), ('\U0002f99e', &['\u83e7']), ('\U0002f99f', &['\u8457']), ('\U0002f9a0',
- &['\u8353']), ('\U0002f9a1', &['\u83ca']), ('\U0002f9a2', &['\u83cc']), ('\U0002f9a3',
- &['\u83dc']), ('\U0002f9a4', &['\U00026c36']), ('\U0002f9a5', &['\U00026d6b']),
- ('\U0002f9a6', &['\U00026cd5']), ('\U0002f9a7', &['\u452b']), ('\U0002f9a8', &['\u84f1']),
- ('\U0002f9a9', &['\u84f3']), ('\U0002f9aa', &['\u8516']), ('\U0002f9ab', &['\U000273ca']),
- ('\U0002f9ac', &['\u8564']), ('\U0002f9ad', &['\U00026f2c']), ('\U0002f9ae', &['\u455d']),
- ('\U0002f9af', &['\u4561']), ('\U0002f9b0', &['\U00026fb1']), ('\U0002f9b1',
- &['\U000270d2']), ('\U0002f9b2', &['\u456b']), ('\U0002f9b3', &['\u8650']), ('\U0002f9b4',
- &['\u865c']), ('\U0002f9b5', &['\u8667']), ('\U0002f9b6', &['\u8669']), ('\U0002f9b7',
- &['\u86a9']), ('\U0002f9b8', &['\u8688']), ('\U0002f9b9', &['\u870e']), ('\U0002f9ba',
- &['\u86e2']), ('\U0002f9bb', &['\u8779']), ('\U0002f9bc', &['\u8728']), ('\U0002f9bd',
- &['\u876b']), ('\U0002f9be', &['\u8786']), ('\U0002f9bf', &['\u45d7']), ('\U0002f9c0',
- &['\u87e1']), ('\U0002f9c1', &['\u8801']), ('\U0002f9c2', &['\u45f9']), ('\U0002f9c3',
- &['\u8860']), ('\U0002f9c4', &['\u8863']), ('\U0002f9c5', &['\U00027667']), ('\U0002f9c6',
- &['\u88d7']), ('\U0002f9c7', &['\u88de']), ('\U0002f9c8', &['\u4635']), ('\U0002f9c9',
- &['\u88fa']), ('\U0002f9ca', &['\u34bb']), ('\U0002f9cb', &['\U000278ae']), ('\U0002f9cc',
- &['\U00027966']), ('\U0002f9cd', &['\u46be']), ('\U0002f9ce', &['\u46c7']), ('\U0002f9cf',
- &['\u8aa0']), ('\U0002f9d0', &['\u8aed']), ('\U0002f9d1', &['\u8b8a']), ('\U0002f9d2',
- &['\u8c55']), ('\U0002f9d3', &['\U00027ca8']), ('\U0002f9d4', &['\u8cab']), ('\U0002f9d5',
- &['\u8cc1']), ('\U0002f9d6', &['\u8d1b']), ('\U0002f9d7', &['\u8d77']), ('\U0002f9d8',
- &['\U00027f2f']), ('\U0002f9d9', &['\U00020804']), ('\U0002f9da', &['\u8dcb']),
- ('\U0002f9db', &['\u8dbc']), ('\U0002f9dc', &['\u8df0']), ('\U0002f9dd', &['\U000208de']),
- ('\U0002f9de', &['\u8ed4']), ('\U0002f9df', &['\u8f38']), ('\U0002f9e0', &['\U000285d2']),
- ('\U0002f9e1', &['\U000285ed']), ('\U0002f9e2', &['\u9094']), ('\U0002f9e3', &['\u90f1']),
- ('\U0002f9e4', &['\u9111']), ('\U0002f9e5', &['\U0002872e']), ('\U0002f9e6', &['\u911b']),
- ('\U0002f9e7', &['\u9238']), ('\U0002f9e8', &['\u92d7']), ('\U0002f9e9', &['\u92d8']),
- ('\U0002f9ea', &['\u927c']), ('\U0002f9eb', &['\u93f9']), ('\U0002f9ec', &['\u9415']),
- ('\U0002f9ed', &['\U00028bfa']), ('\U0002f9ee', &['\u958b']), ('\U0002f9ef', &['\u4995']),
- ('\U0002f9f0', &['\u95b7']), ('\U0002f9f1', &['\U00028d77']), ('\U0002f9f2', &['\u49e6']),
- ('\U0002f9f3', &['\u96c3']), ('\U0002f9f4', &['\u5db2']), ('\U0002f9f5', &['\u9723']),
- ('\U0002f9f6', &['\U00029145']), ('\U0002f9f7', &['\U0002921a']), ('\U0002f9f8',
- &['\u4a6e']), ('\U0002f9f9', &['\u4a76']), ('\U0002f9fa', &['\u97e0']), ('\U0002f9fb',
- &['\U0002940a']), ('\U0002f9fc', &['\u4ab2']), ('\U0002f9fd', &['\U00029496']),
- ('\U0002f9fe', &['\u980b']), ('\U0002f9ff', &['\u980b']), ('\U0002fa00', &['\u9829']),
- ('\U0002fa01', &['\U000295b6']), ('\U0002fa02', &['\u98e2']), ('\U0002fa03', &['\u4b33']),
- ('\U0002fa04', &['\u9929']), ('\U0002fa05', &['\u99a7']), ('\U0002fa06', &['\u99c2']),
- ('\U0002fa07', &['\u99fe']), ('\U0002fa08', &['\u4bce']), ('\U0002fa09', &['\U00029b30']),
- ('\U0002fa0a', &['\u9b12']), ('\U0002fa0b', &['\u9c40']), ('\U0002fa0c', &['\u9cfd']),
- ('\U0002fa0d', &['\u4cce']), ('\U0002fa0e', &['\u4ced']), ('\U0002fa0f', &['\u9d67']),
- ('\U0002fa10', &['\U0002a0ce']), ('\U0002fa11', &['\u4cf8']), ('\U0002fa12',
- &['\U0002a105']), ('\U0002fa13', &['\U0002a20e']), ('\U0002fa14', &['\U0002a291']),
- ('\U0002fa15', &['\u9ebb']), ('\U0002fa16', &['\u4d56']), ('\U0002fa17', &['\u9ef9']),
- ('\U0002fa18', &['\u9efe']), ('\U0002fa19', &['\u9f05']), ('\U0002fa1a', &['\u9f0f']),
- ('\U0002fa1b', &['\u9f16']), ('\U0002fa1c', &['\u9f3b']), ('\U0002fa1d', &['\U0002a600'])
- ];
-
- // Compatibility decompositions
- static compatibility_table : &'static [(char, &'static [char])] = &[
- ('\xa0', &['\x20']), ('\xa8', &['\x20', '\u0308']), ('\xaa', &['\x61']), ('\xaf', &['\x20',
- '\u0304']), ('\xb2', &['\x32']), ('\xb3', &['\x33']), ('\xb4', &['\x20', '\u0301']),
- ('\xb5', &['\u03bc']), ('\xb8', &['\x20', '\u0327']), ('\xb9', &['\x31']), ('\xba',
- &['\x6f']), ('\xbc', &['\x31', '\u2044', '\x34']), ('\xbd', &['\x31', '\u2044', '\x32']),
- ('\xbe', &['\x33', '\u2044', '\x34']), ('\u0132', &['\x49', '\x4a']), ('\u0133', &['\x69',
- '\x6a']), ('\u013f', &['\x4c', '\xb7']), ('\u0140', &['\x6c', '\xb7']), ('\u0149',
- &['\u02bc', '\x6e']), ('\u017f', &['\x73']), ('\u01c4', &['\x44', '\u017d']), ('\u01c5',
- &['\x44', '\u017e']), ('\u01c6', &['\x64', '\u017e']), ('\u01c7', &['\x4c', '\x4a']),
- ('\u01c8', &['\x4c', '\x6a']), ('\u01c9', &['\x6c', '\x6a']), ('\u01ca', &['\x4e', '\x4a']),
- ('\u01cb', &['\x4e', '\x6a']), ('\u01cc', &['\x6e', '\x6a']), ('\u01f1', &['\x44', '\x5a']),
- ('\u01f2', &['\x44', '\x7a']), ('\u01f3', &['\x64', '\x7a']), ('\u02b0', &['\x68']),
- ('\u02b1', &['\u0266']), ('\u02b2', &['\x6a']), ('\u02b3', &['\x72']), ('\u02b4',
- &['\u0279']), ('\u02b5', &['\u027b']), ('\u02b6', &['\u0281']), ('\u02b7', &['\x77']),
- ('\u02b8', &['\x79']), ('\u02d8', &['\x20', '\u0306']), ('\u02d9', &['\x20', '\u0307']),
- ('\u02da', &['\x20', '\u030a']), ('\u02db', &['\x20', '\u0328']), ('\u02dc', &['\x20',
- '\u0303']), ('\u02dd', &['\x20', '\u030b']), ('\u02e0', &['\u0263']), ('\u02e1', &['\x6c']),
- ('\u02e2', &['\x73']), ('\u02e3', &['\x78']), ('\u02e4', &['\u0295']), ('\u037a', &['\x20',
- '\u0345']), ('\u0384', &['\x20', '\u0301']), ('\u03d0', &['\u03b2']), ('\u03d1',
- &['\u03b8']), ('\u03d2', &['\u03a5']), ('\u03d5', &['\u03c6']), ('\u03d6', &['\u03c0']),
- ('\u03f0', &['\u03ba']), ('\u03f1', &['\u03c1']), ('\u03f2', &['\u03c2']), ('\u03f4',
- &['\u0398']), ('\u03f5', &['\u03b5']), ('\u03f9', &['\u03a3']), ('\u0587', &['\u0565',
- '\u0582']), ('\u0675', &['\u0627', '\u0674']), ('\u0676', &['\u0648', '\u0674']), ('\u0677',
- &['\u06c7', '\u0674']), ('\u0678', &['\u064a', '\u0674']), ('\u0e33', &['\u0e4d',
- '\u0e32']), ('\u0eb3', &['\u0ecd', '\u0eb2']), ('\u0edc', &['\u0eab', '\u0e99']), ('\u0edd',
- &['\u0eab', '\u0ea1']), ('\u0f0c', &['\u0f0b']), ('\u0f77', &['\u0fb2', '\u0f81']),
- ('\u0f79', &['\u0fb3', '\u0f81']), ('\u10fc', &['\u10dc']), ('\u1d2c', &['\x41']),
- ('\u1d2d', &['\xc6']), ('\u1d2e', &['\x42']), ('\u1d30', &['\x44']), ('\u1d31', &['\x45']),
- ('\u1d32', &['\u018e']), ('\u1d33', &['\x47']), ('\u1d34', &['\x48']), ('\u1d35',
- &['\x49']), ('\u1d36', &['\x4a']), ('\u1d37', &['\x4b']), ('\u1d38', &['\x4c']), ('\u1d39',
- &['\x4d']), ('\u1d3a', &['\x4e']), ('\u1d3c', &['\x4f']), ('\u1d3d', &['\u0222']),
- ('\u1d3e', &['\x50']), ('\u1d3f', &['\x52']), ('\u1d40', &['\x54']), ('\u1d41', &['\x55']),
- ('\u1d42', &['\x57']), ('\u1d43', &['\x61']), ('\u1d44', &['\u0250']), ('\u1d45',
- &['\u0251']), ('\u1d46', &['\u1d02']), ('\u1d47', &['\x62']), ('\u1d48', &['\x64']),
- ('\u1d49', &['\x65']), ('\u1d4a', &['\u0259']), ('\u1d4b', &['\u025b']), ('\u1d4c',
- &['\u025c']), ('\u1d4d', &['\x67']), ('\u1d4f', &['\x6b']), ('\u1d50', &['\x6d']),
- ('\u1d51', &['\u014b']), ('\u1d52', &['\x6f']), ('\u1d53', &['\u0254']), ('\u1d54',
- &['\u1d16']), ('\u1d55', &['\u1d17']), ('\u1d56', &['\x70']), ('\u1d57', &['\x74']),
- ('\u1d58', &['\x75']), ('\u1d59', &['\u1d1d']), ('\u1d5a', &['\u026f']), ('\u1d5b',
- &['\x76']), ('\u1d5c', &['\u1d25']), ('\u1d5d', &['\u03b2']), ('\u1d5e', &['\u03b3']),
- ('\u1d5f', &['\u03b4']), ('\u1d60', &['\u03c6']), ('\u1d61', &['\u03c7']), ('\u1d62',
- &['\x69']), ('\u1d63', &['\x72']), ('\u1d64', &['\x75']), ('\u1d65', &['\x76']), ('\u1d66',
- &['\u03b2']), ('\u1d67', &['\u03b3']), ('\u1d68', &['\u03c1']), ('\u1d69', &['\u03c6']),
- ('\u1d6a', &['\u03c7']), ('\u1d78', &['\u043d']), ('\u1d9b', &['\u0252']), ('\u1d9c',
- &['\x63']), ('\u1d9d', &['\u0255']), ('\u1d9e', &['\xf0']), ('\u1d9f', &['\u025c']),
- ('\u1da0', &['\x66']), ('\u1da1', &['\u025f']), ('\u1da2', &['\u0261']), ('\u1da3',
- &['\u0265']), ('\u1da4', &['\u0268']), ('\u1da5', &['\u0269']), ('\u1da6', &['\u026a']),
- ('\u1da7', &['\u1d7b']), ('\u1da8', &['\u029d']), ('\u1da9', &['\u026d']), ('\u1daa',
- &['\u1d85']), ('\u1dab', &['\u029f']), ('\u1dac', &['\u0271']), ('\u1dad', &['\u0270']),
- ('\u1dae', &['\u0272']), ('\u1daf', &['\u0273']), ('\u1db0', &['\u0274']), ('\u1db1',
- &['\u0275']), ('\u1db2', &['\u0278']), ('\u1db3', &['\u0282']), ('\u1db4', &['\u0283']),
- ('\u1db5', &['\u01ab']), ('\u1db6', &['\u0289']), ('\u1db7', &['\u028a']), ('\u1db8',
- &['\u1d1c']), ('\u1db9', &['\u028b']), ('\u1dba', &['\u028c']), ('\u1dbb', &['\x7a']),
- ('\u1dbc', &['\u0290']), ('\u1dbd', &['\u0291']), ('\u1dbe', &['\u0292']), ('\u1dbf',
- &['\u03b8']), ('\u1e9a', &['\x61', '\u02be']), ('\u1fbd', &['\x20', '\u0313']), ('\u1fbf',
- &['\x20', '\u0313']), ('\u1fc0', &['\x20', '\u0342']), ('\u1ffe', &['\x20', '\u0314']),
- ('\u2002', &['\x20']), ('\u2003', &['\x20']), ('\u2004', &['\x20']), ('\u2005', &['\x20']),
- ('\u2006', &['\x20']), ('\u2007', &['\x20']), ('\u2008', &['\x20']), ('\u2009', &['\x20']),
- ('\u200a', &['\x20']), ('\u2011', &['\u2010']), ('\u2017', &['\x20', '\u0333']), ('\u2024',
- &['\x2e']), ('\u2025', &['\x2e', '\x2e']), ('\u2026', &['\x2e', '\x2e', '\x2e']), ('\u202f',
- &['\x20']), ('\u2033', &['\u2032', '\u2032']), ('\u2034', &['\u2032', '\u2032', '\u2032']),
- ('\u2036', &['\u2035', '\u2035']), ('\u2037', &['\u2035', '\u2035', '\u2035']), ('\u203c',
- &['\x21', '\x21']), ('\u203e', &['\x20', '\u0305']), ('\u2047', &['\x3f', '\x3f']),
- ('\u2048', &['\x3f', '\x21']), ('\u2049', &['\x21', '\x3f']), ('\u2057', &['\u2032',
- '\u2032', '\u2032', '\u2032']), ('\u205f', &['\x20']), ('\u2070', &['\x30']), ('\u2071',
- &['\x69']), ('\u2074', &['\x34']), ('\u2075', &['\x35']), ('\u2076', &['\x36']), ('\u2077',
- &['\x37']), ('\u2078', &['\x38']), ('\u2079', &['\x39']), ('\u207a', &['\x2b']), ('\u207b',
- &['\u2212']), ('\u207c', &['\x3d']), ('\u207d', &['\x28']), ('\u207e', &['\x29']),
- ('\u207f', &['\x6e']), ('\u2080', &['\x30']), ('\u2081', &['\x31']), ('\u2082', &['\x32']),
- ('\u2083', &['\x33']), ('\u2084', &['\x34']), ('\u2085', &['\x35']), ('\u2086', &['\x36']),
- ('\u2087', &['\x37']), ('\u2088', &['\x38']), ('\u2089', &['\x39']), ('\u208a', &['\x2b']),
- ('\u208b', &['\u2212']), ('\u208c', &['\x3d']), ('\u208d', &['\x28']), ('\u208e',
- &['\x29']), ('\u2090', &['\x61']), ('\u2091', &['\x65']), ('\u2092', &['\x6f']), ('\u2093',
- &['\x78']), ('\u2094', &['\u0259']), ('\u2095', &['\x68']), ('\u2096', &['\x6b']),
- ('\u2097', &['\x6c']), ('\u2098', &['\x6d']), ('\u2099', &['\x6e']), ('\u209a', &['\x70']),
- ('\u209b', &['\x73']), ('\u209c', &['\x74']), ('\u20a8', &['\x52', '\x73']), ('\u2100',
- &['\x61', '\x2f', '\x63']), ('\u2101', &['\x61', '\x2f', '\x73']), ('\u2102', &['\x43']),
- ('\u2103', &['\xb0', '\x43']), ('\u2105', &['\x63', '\x2f', '\x6f']), ('\u2106', &['\x63',
- '\x2f', '\x75']), ('\u2107', &['\u0190']), ('\u2109', &['\xb0', '\x46']), ('\u210a',
- &['\x67']), ('\u210b', &['\x48']), ('\u210c', &['\x48']), ('\u210d', &['\x48']), ('\u210e',
- &['\x68']), ('\u210f', &['\u0127']), ('\u2110', &['\x49']), ('\u2111', &['\x49']),
- ('\u2112', &['\x4c']), ('\u2113', &['\x6c']), ('\u2115', &['\x4e']), ('\u2116', &['\x4e',
- '\x6f']), ('\u2119', &['\x50']), ('\u211a', &['\x51']), ('\u211b', &['\x52']), ('\u211c',
- &['\x52']), ('\u211d', &['\x52']), ('\u2120', &['\x53', '\x4d']), ('\u2121', &['\x54',
- '\x45', '\x4c']), ('\u2122', &['\x54', '\x4d']), ('\u2124', &['\x5a']), ('\u2128',
- &['\x5a']), ('\u212c', &['\x42']), ('\u212d', &['\x43']), ('\u212f', &['\x65']), ('\u2130',
- &['\x45']), ('\u2131', &['\x46']), ('\u2133', &['\x4d']), ('\u2134', &['\x6f']), ('\u2135',
- &['\u05d0']), ('\u2136', &['\u05d1']), ('\u2137', &['\u05d2']), ('\u2138', &['\u05d3']),
- ('\u2139', &['\x69']), ('\u213b', &['\x46', '\x41', '\x58']), ('\u213c', &['\u03c0']),
- ('\u213d', &['\u03b3']), ('\u213e', &['\u0393']), ('\u213f', &['\u03a0']), ('\u2140',
- &['\u2211']), ('\u2145', &['\x44']), ('\u2146', &['\x64']), ('\u2147', &['\x65']),
- ('\u2148', &['\x69']), ('\u2149', &['\x6a']), ('\u2150', &['\x31', '\u2044', '\x37']),
- ('\u2151', &['\x31', '\u2044', '\x39']), ('\u2152', &['\x31', '\u2044', '\x31', '\x30']),
- ('\u2153', &['\x31', '\u2044', '\x33']), ('\u2154', &['\x32', '\u2044', '\x33']), ('\u2155',
- &['\x31', '\u2044', '\x35']), ('\u2156', &['\x32', '\u2044', '\x35']), ('\u2157', &['\x33',
- '\u2044', '\x35']), ('\u2158', &['\x34', '\u2044', '\x35']), ('\u2159', &['\x31', '\u2044',
- '\x36']), ('\u215a', &['\x35', '\u2044', '\x36']), ('\u215b', &['\x31', '\u2044', '\x38']),
- ('\u215c', &['\x33', '\u2044', '\x38']), ('\u215d', &['\x35', '\u2044', '\x38']), ('\u215e',
- &['\x37', '\u2044', '\x38']), ('\u215f', &['\x31', '\u2044']), ('\u2160', &['\x49']),
- ('\u2161', &['\x49', '\x49']), ('\u2162', &['\x49', '\x49', '\x49']), ('\u2163', &['\x49',
- '\x56']), ('\u2164', &['\x56']), ('\u2165', &['\x56', '\x49']), ('\u2166', &['\x56', '\x49',
- '\x49']), ('\u2167', &['\x56', '\x49', '\x49', '\x49']), ('\u2168', &['\x49', '\x58']),
- ('\u2169', &['\x58']), ('\u216a', &['\x58', '\x49']), ('\u216b', &['\x58', '\x49', '\x49']),
- ('\u216c', &['\x4c']), ('\u216d', &['\x43']), ('\u216e', &['\x44']), ('\u216f', &['\x4d']),
- ('\u2170', &['\x69']), ('\u2171', &['\x69', '\x69']), ('\u2172', &['\x69', '\x69', '\x69']),
- ('\u2173', &['\x69', '\x76']), ('\u2174', &['\x76']), ('\u2175', &['\x76', '\x69']),
- ('\u2176', &['\x76', '\x69', '\x69']), ('\u2177', &['\x76', '\x69', '\x69', '\x69']),
- ('\u2178', &['\x69', '\x78']), ('\u2179', &['\x78']), ('\u217a', &['\x78', '\x69']),
- ('\u217b', &['\x78', '\x69', '\x69']), ('\u217c', &['\x6c']), ('\u217d', &['\x63']),
- ('\u217e', &['\x64']), ('\u217f', &['\x6d']), ('\u2189', &['\x30', '\u2044', '\x33']),
- ('\u222c', &['\u222b', '\u222b']), ('\u222d', &['\u222b', '\u222b', '\u222b']), ('\u222f',
- &['\u222e', '\u222e']), ('\u2230', &['\u222e', '\u222e', '\u222e']), ('\u2460', &['\x31']),
- ('\u2461', &['\x32']), ('\u2462', &['\x33']), ('\u2463', &['\x34']), ('\u2464', &['\x35']),
- ('\u2465', &['\x36']), ('\u2466', &['\x37']), ('\u2467', &['\x38']), ('\u2468', &['\x39']),
- ('\u2469', &['\x31', '\x30']), ('\u246a', &['\x31', '\x31']), ('\u246b', &['\x31', '\x32']),
- ('\u246c', &['\x31', '\x33']), ('\u246d', &['\x31', '\x34']), ('\u246e', &['\x31', '\x35']),
- ('\u246f', &['\x31', '\x36']), ('\u2470', &['\x31', '\x37']), ('\u2471', &['\x31', '\x38']),
- ('\u2472', &['\x31', '\x39']), ('\u2473', &['\x32', '\x30']), ('\u2474', &['\x28', '\x31',
- '\x29']), ('\u2475', &['\x28', '\x32', '\x29']), ('\u2476', &['\x28', '\x33', '\x29']),
- ('\u2477', &['\x28', '\x34', '\x29']), ('\u2478', &['\x28', '\x35', '\x29']), ('\u2479',
- &['\x28', '\x36', '\x29']), ('\u247a', &['\x28', '\x37', '\x29']), ('\u247b', &['\x28',
- '\x38', '\x29']), ('\u247c', &['\x28', '\x39', '\x29']), ('\u247d', &['\x28', '\x31',
- '\x30', '\x29']), ('\u247e', &['\x28', '\x31', '\x31', '\x29']), ('\u247f', &['\x28',
- '\x31', '\x32', '\x29']), ('\u2480', &['\x28', '\x31', '\x33', '\x29']), ('\u2481',
- &['\x28', '\x31', '\x34', '\x29']), ('\u2482', &['\x28', '\x31', '\x35', '\x29']),
- ('\u2483', &['\x28', '\x31', '\x36', '\x29']), ('\u2484', &['\x28', '\x31', '\x37',
- '\x29']), ('\u2485', &['\x28', '\x31', '\x38', '\x29']), ('\u2486', &['\x28', '\x31',
- '\x39', '\x29']), ('\u2487', &['\x28', '\x32', '\x30', '\x29']), ('\u2488', &['\x31',
- '\x2e']), ('\u2489', &['\x32', '\x2e']), ('\u248a', &['\x33', '\x2e']), ('\u248b', &['\x34',
- '\x2e']), ('\u248c', &['\x35', '\x2e']), ('\u248d', &['\x36', '\x2e']), ('\u248e', &['\x37',
- '\x2e']), ('\u248f', &['\x38', '\x2e']), ('\u2490', &['\x39', '\x2e']), ('\u2491', &['\x31',
- '\x30', '\x2e']), ('\u2492', &['\x31', '\x31', '\x2e']), ('\u2493', &['\x31', '\x32',
- '\x2e']), ('\u2494', &['\x31', '\x33', '\x2e']), ('\u2495', &['\x31', '\x34', '\x2e']),
- ('\u2496', &['\x31', '\x35', '\x2e']), ('\u2497', &['\x31', '\x36', '\x2e']), ('\u2498',
- &['\x31', '\x37', '\x2e']), ('\u2499', &['\x31', '\x38', '\x2e']), ('\u249a', &['\x31',
- '\x39', '\x2e']), ('\u249b', &['\x32', '\x30', '\x2e']), ('\u249c', &['\x28', '\x61',
- '\x29']), ('\u249d', &['\x28', '\x62', '\x29']), ('\u249e', &['\x28', '\x63', '\x29']),
- ('\u249f', &['\x28', '\x64', '\x29']), ('\u24a0', &['\x28', '\x65', '\x29']), ('\u24a1',
- &['\x28', '\x66', '\x29']), ('\u24a2', &['\x28', '\x67', '\x29']), ('\u24a3', &['\x28',
- '\x68', '\x29']), ('\u24a4', &['\x28', '\x69', '\x29']), ('\u24a5', &['\x28', '\x6a',
- '\x29']), ('\u24a6', &['\x28', '\x6b', '\x29']), ('\u24a7', &['\x28', '\x6c', '\x29']),
- ('\u24a8', &['\x28', '\x6d', '\x29']), ('\u24a9', &['\x28', '\x6e', '\x29']), ('\u24aa',
- &['\x28', '\x6f', '\x29']), ('\u24ab', &['\x28', '\x70', '\x29']), ('\u24ac', &['\x28',
- '\x71', '\x29']), ('\u24ad', &['\x28', '\x72', '\x29']), ('\u24ae', &['\x28', '\x73',
- '\x29']), ('\u24af', &['\x28', '\x74', '\x29']), ('\u24b0', &['\x28', '\x75', '\x29']),
- ('\u24b1', &['\x28', '\x76', '\x29']), ('\u24b2', &['\x28', '\x77', '\x29']), ('\u24b3',
- &['\x28', '\x78', '\x29']), ('\u24b4', &['\x28', '\x79', '\x29']), ('\u24b5', &['\x28',
- '\x7a', '\x29']), ('\u24b6', &['\x41']), ('\u24b7', &['\x42']), ('\u24b8', &['\x43']),
- ('\u24b9', &['\x44']), ('\u24ba', &['\x45']), ('\u24bb', &['\x46']), ('\u24bc', &['\x47']),
- ('\u24bd', &['\x48']), ('\u24be', &['\x49']), ('\u24bf', &['\x4a']), ('\u24c0', &['\x4b']),
- ('\u24c1', &['\x4c']), ('\u24c2', &['\x4d']), ('\u24c3', &['\x4e']), ('\u24c4', &['\x4f']),
- ('\u24c5', &['\x50']), ('\u24c6', &['\x51']), ('\u24c7', &['\x52']), ('\u24c8', &['\x53']),
- ('\u24c9', &['\x54']), ('\u24ca', &['\x55']), ('\u24cb', &['\x56']), ('\u24cc', &['\x57']),
- ('\u24cd', &['\x58']), ('\u24ce', &['\x59']), ('\u24cf', &['\x5a']), ('\u24d0', &['\x61']),
- ('\u24d1', &['\x62']), ('\u24d2', &['\x63']), ('\u24d3', &['\x64']), ('\u24d4', &['\x65']),
- ('\u24d5', &['\x66']), ('\u24d6', &['\x67']), ('\u24d7', &['\x68']), ('\u24d8', &['\x69']),
- ('\u24d9', &['\x6a']), ('\u24da', &['\x6b']), ('\u24db', &['\x6c']), ('\u24dc', &['\x6d']),
- ('\u24dd', &['\x6e']), ('\u24de', &['\x6f']), ('\u24df', &['\x70']), ('\u24e0', &['\x71']),
- ('\u24e1', &['\x72']), ('\u24e2', &['\x73']), ('\u24e3', &['\x74']), ('\u24e4', &['\x75']),
- ('\u24e5', &['\x76']), ('\u24e6', &['\x77']), ('\u24e7', &['\x78']), ('\u24e8', &['\x79']),
- ('\u24e9', &['\x7a']), ('\u24ea', &['\x30']), ('\u2a0c', &['\u222b', '\u222b', '\u222b',
- '\u222b']), ('\u2a74', &['\x3a', '\x3a', '\x3d']), ('\u2a75', &['\x3d', '\x3d']), ('\u2a76',
- &['\x3d', '\x3d', '\x3d']), ('\u2c7c', &['\x6a']), ('\u2c7d', &['\x56']), ('\u2d6f',
- &['\u2d61']), ('\u2e9f', &['\u6bcd']), ('\u2ef3', &['\u9f9f']), ('\u2f00', &['\u4e00']),
- ('\u2f01', &['\u4e28']), ('\u2f02', &['\u4e36']), ('\u2f03', &['\u4e3f']), ('\u2f04',
- &['\u4e59']), ('\u2f05', &['\u4e85']), ('\u2f06', &['\u4e8c']), ('\u2f07', &['\u4ea0']),
- ('\u2f08', &['\u4eba']), ('\u2f09', &['\u513f']), ('\u2f0a', &['\u5165']), ('\u2f0b',
- &['\u516b']), ('\u2f0c', &['\u5182']), ('\u2f0d', &['\u5196']), ('\u2f0e', &['\u51ab']),
- ('\u2f0f', &['\u51e0']), ('\u2f10', &['\u51f5']), ('\u2f11', &['\u5200']), ('\u2f12',
- &['\u529b']), ('\u2f13', &['\u52f9']), ('\u2f14', &['\u5315']), ('\u2f15', &['\u531a']),
- ('\u2f16', &['\u5338']), ('\u2f17', &['\u5341']), ('\u2f18', &['\u535c']), ('\u2f19',
- &['\u5369']), ('\u2f1a', &['\u5382']), ('\u2f1b', &['\u53b6']), ('\u2f1c', &['\u53c8']),
- ('\u2f1d', &['\u53e3']), ('\u2f1e', &['\u56d7']), ('\u2f1f', &['\u571f']), ('\u2f20',
- &['\u58eb']), ('\u2f21', &['\u5902']), ('\u2f22', &['\u590a']), ('\u2f23', &['\u5915']),
- ('\u2f24', &['\u5927']), ('\u2f25', &['\u5973']), ('\u2f26', &['\u5b50']), ('\u2f27',
- &['\u5b80']), ('\u2f28', &['\u5bf8']), ('\u2f29', &['\u5c0f']), ('\u2f2a', &['\u5c22']),
- ('\u2f2b', &['\u5c38']), ('\u2f2c', &['\u5c6e']), ('\u2f2d', &['\u5c71']), ('\u2f2e',
- &['\u5ddb']), ('\u2f2f', &['\u5de5']), ('\u2f30', &['\u5df1']), ('\u2f31', &['\u5dfe']),
- ('\u2f32', &['\u5e72']), ('\u2f33', &['\u5e7a']), ('\u2f34', &['\u5e7f']), ('\u2f35',
- &['\u5ef4']), ('\u2f36', &['\u5efe']), ('\u2f37', &['\u5f0b']), ('\u2f38', &['\u5f13']),
- ('\u2f39', &['\u5f50']), ('\u2f3a', &['\u5f61']), ('\u2f3b', &['\u5f73']), ('\u2f3c',
- &['\u5fc3']), ('\u2f3d', &['\u6208']), ('\u2f3e', &['\u6236']), ('\u2f3f', &['\u624b']),
- ('\u2f40', &['\u652f']), ('\u2f41', &['\u6534']), ('\u2f42', &['\u6587']), ('\u2f43',
- &['\u6597']), ('\u2f44', &['\u65a4']), ('\u2f45', &['\u65b9']), ('\u2f46', &['\u65e0']),
- ('\u2f47', &['\u65e5']), ('\u2f48', &['\u66f0']), ('\u2f49', &['\u6708']), ('\u2f4a',
- &['\u6728']), ('\u2f4b', &['\u6b20']), ('\u2f4c', &['\u6b62']), ('\u2f4d', &['\u6b79']),
- ('\u2f4e', &['\u6bb3']), ('\u2f4f', &['\u6bcb']), ('\u2f50', &['\u6bd4']), ('\u2f51',
- &['\u6bdb']), ('\u2f52', &['\u6c0f']), ('\u2f53', &['\u6c14']), ('\u2f54', &['\u6c34']),
- ('\u2f55', &['\u706b']), ('\u2f56', &['\u722a']), ('\u2f57', &['\u7236']), ('\u2f58',
- &['\u723b']), ('\u2f59', &['\u723f']), ('\u2f5a', &['\u7247']), ('\u2f5b', &['\u7259']),
- ('\u2f5c', &['\u725b']), ('\u2f5d', &['\u72ac']), ('\u2f5e', &['\u7384']), ('\u2f5f',
- &['\u7389']), ('\u2f60', &['\u74dc']), ('\u2f61', &['\u74e6']), ('\u2f62', &['\u7518']),
- ('\u2f63', &['\u751f']), ('\u2f64', &['\u7528']), ('\u2f65', &['\u7530']), ('\u2f66',
- &['\u758b']), ('\u2f67', &['\u7592']), ('\u2f68', &['\u7676']), ('\u2f69', &['\u767d']),
- ('\u2f6a', &['\u76ae']), ('\u2f6b', &['\u76bf']), ('\u2f6c', &['\u76ee']), ('\u2f6d',
- &['\u77db']), ('\u2f6e', &['\u77e2']), ('\u2f6f', &['\u77f3']), ('\u2f70', &['\u793a']),
- ('\u2f71', &['\u79b8']), ('\u2f72', &['\u79be']), ('\u2f73', &['\u7a74']), ('\u2f74',
- &['\u7acb']), ('\u2f75', &['\u7af9']), ('\u2f76', &['\u7c73']), ('\u2f77', &['\u7cf8']),
- ('\u2f78', &['\u7f36']), ('\u2f79', &['\u7f51']), ('\u2f7a', &['\u7f8a']), ('\u2f7b',
- &['\u7fbd']), ('\u2f7c', &['\u8001']), ('\u2f7d', &['\u800c']), ('\u2f7e', &['\u8012']),
- ('\u2f7f', &['\u8033']), ('\u2f80', &['\u807f']), ('\u2f81', &['\u8089']), ('\u2f82',
- &['\u81e3']), ('\u2f83', &['\u81ea']), ('\u2f84', &['\u81f3']), ('\u2f85', &['\u81fc']),
- ('\u2f86', &['\u820c']), ('\u2f87', &['\u821b']), ('\u2f88', &['\u821f']), ('\u2f89',
- &['\u826e']), ('\u2f8a', &['\u8272']), ('\u2f8b', &['\u8278']), ('\u2f8c', &['\u864d']),
- ('\u2f8d', &['\u866b']), ('\u2f8e', &['\u8840']), ('\u2f8f', &['\u884c']), ('\u2f90',
- &['\u8863']), ('\u2f91', &['\u897e']), ('\u2f92', &['\u898b']), ('\u2f93', &['\u89d2']),
- ('\u2f94', &['\u8a00']), ('\u2f95', &['\u8c37']), ('\u2f96', &['\u8c46']), ('\u2f97',
- &['\u8c55']), ('\u2f98', &['\u8c78']), ('\u2f99', &['\u8c9d']), ('\u2f9a', &['\u8d64']),
- ('\u2f9b', &['\u8d70']), ('\u2f9c', &['\u8db3']), ('\u2f9d', &['\u8eab']), ('\u2f9e',
- &['\u8eca']), ('\u2f9f', &['\u8f9b']), ('\u2fa0', &['\u8fb0']), ('\u2fa1', &['\u8fb5']),
- ('\u2fa2', &['\u9091']), ('\u2fa3', &['\u9149']), ('\u2fa4', &['\u91c6']), ('\u2fa5',
- &['\u91cc']), ('\u2fa6', &['\u91d1']), ('\u2fa7', &['\u9577']), ('\u2fa8', &['\u9580']),
- ('\u2fa9', &['\u961c']), ('\u2faa', &['\u96b6']), ('\u2fab', &['\u96b9']), ('\u2fac',
- &['\u96e8']), ('\u2fad', &['\u9751']), ('\u2fae', &['\u975e']), ('\u2faf', &['\u9762']),
- ('\u2fb0', &['\u9769']), ('\u2fb1', &['\u97cb']), ('\u2fb2', &['\u97ed']), ('\u2fb3',
- &['\u97f3']), ('\u2fb4', &['\u9801']), ('\u2fb5', &['\u98a8']), ('\u2fb6', &['\u98db']),
- ('\u2fb7', &['\u98df']), ('\u2fb8', &['\u9996']), ('\u2fb9', &['\u9999']), ('\u2fba',
- &['\u99ac']), ('\u2fbb', &['\u9aa8']), ('\u2fbc', &['\u9ad8']), ('\u2fbd', &['\u9adf']),
- ('\u2fbe', &['\u9b25']), ('\u2fbf', &['\u9b2f']), ('\u2fc0', &['\u9b32']), ('\u2fc1',
- &['\u9b3c']), ('\u2fc2', &['\u9b5a']), ('\u2fc3', &['\u9ce5']), ('\u2fc4', &['\u9e75']),
- ('\u2fc5', &['\u9e7f']), ('\u2fc6', &['\u9ea5']), ('\u2fc7', &['\u9ebb']), ('\u2fc8',
- &['\u9ec3']), ('\u2fc9', &['\u9ecd']), ('\u2fca', &['\u9ed1']), ('\u2fcb', &['\u9ef9']),
- ('\u2fcc', &['\u9efd']), ('\u2fcd', &['\u9f0e']), ('\u2fce', &['\u9f13']), ('\u2fcf',
- &['\u9f20']), ('\u2fd0', &['\u9f3b']), ('\u2fd1', &['\u9f4a']), ('\u2fd2', &['\u9f52']),
- ('\u2fd3', &['\u9f8d']), ('\u2fd4', &['\u9f9c']), ('\u2fd5', &['\u9fa0']), ('\u3000',
- &['\x20']), ('\u3036', &['\u3012']), ('\u3038', &['\u5341']), ('\u3039', &['\u5344']),
- ('\u303a', &['\u5345']), ('\u309b', &['\x20', '\u3099']), ('\u309c', &['\x20', '\u309a']),
- ('\u309f', &['\u3088', '\u308a']), ('\u30ff', &['\u30b3', '\u30c8']), ('\u3131',
- &['\u1100']), ('\u3132', &['\u1101']), ('\u3133', &['\u11aa']), ('\u3134', &['\u1102']),
- ('\u3135', &['\u11ac']), ('\u3136', &['\u11ad']), ('\u3137', &['\u1103']), ('\u3138',
- &['\u1104']), ('\u3139', &['\u1105']), ('\u313a', &['\u11b0']), ('\u313b', &['\u11b1']),
- ('\u313c', &['\u11b2']), ('\u313d', &['\u11b3']), ('\u313e', &['\u11b4']), ('\u313f',
- &['\u11b5']), ('\u3140', &['\u111a']), ('\u3141', &['\u1106']), ('\u3142', &['\u1107']),
- ('\u3143', &['\u1108']), ('\u3144', &['\u1121']), ('\u3145', &['\u1109']), ('\u3146',
- &['\u110a']), ('\u3147', &['\u110b']), ('\u3148', &['\u110c']), ('\u3149', &['\u110d']),
- ('\u314a', &['\u110e']), ('\u314b', &['\u110f']), ('\u314c', &['\u1110']), ('\u314d',
- &['\u1111']), ('\u314e', &['\u1112']), ('\u314f', &['\u1161']), ('\u3150', &['\u1162']),
- ('\u3151', &['\u1163']), ('\u3152', &['\u1164']), ('\u3153', &['\u1165']), ('\u3154',
- &['\u1166']), ('\u3155', &['\u1167']), ('\u3156', &['\u1168']), ('\u3157', &['\u1169']),
- ('\u3158', &['\u116a']), ('\u3159', &['\u116b']), ('\u315a', &['\u116c']), ('\u315b',
- &['\u116d']), ('\u315c', &['\u116e']), ('\u315d', &['\u116f']), ('\u315e', &['\u1170']),
- ('\u315f', &['\u1171']), ('\u3160', &['\u1172']), ('\u3161', &['\u1173']), ('\u3162',
- &['\u1174']), ('\u3163', &['\u1175']), ('\u3164', &['\u1160']), ('\u3165', &['\u1114']),
- ('\u3166', &['\u1115']), ('\u3167', &['\u11c7']), ('\u3168', &['\u11c8']), ('\u3169',
- &['\u11cc']), ('\u316a', &['\u11ce']), ('\u316b', &['\u11d3']), ('\u316c', &['\u11d7']),
- ('\u316d', &['\u11d9']), ('\u316e', &['\u111c']), ('\u316f', &['\u11dd']), ('\u3170',
- &['\u11df']), ('\u3171', &['\u111d']), ('\u3172', &['\u111e']), ('\u3173', &['\u1120']),
- ('\u3174', &['\u1122']), ('\u3175', &['\u1123']), ('\u3176', &['\u1127']), ('\u3177',
- &['\u1129']), ('\u3178', &['\u112b']), ('\u3179', &['\u112c']), ('\u317a', &['\u112d']),
- ('\u317b', &['\u112e']), ('\u317c', &['\u112f']), ('\u317d', &['\u1132']), ('\u317e',
- &['\u1136']), ('\u317f', &['\u1140']), ('\u3180', &['\u1147']), ('\u3181', &['\u114c']),
- ('\u3182', &['\u11f1']), ('\u3183', &['\u11f2']), ('\u3184', &['\u1157']), ('\u3185',
- &['\u1158']), ('\u3186', &['\u1159']), ('\u3187', &['\u1184']), ('\u3188', &['\u1185']),
- ('\u3189', &['\u1188']), ('\u318a', &['\u1191']), ('\u318b', &['\u1192']), ('\u318c',
- &['\u1194']), ('\u318d', &['\u119e']), ('\u318e', &['\u11a1']), ('\u3192', &['\u4e00']),
- ('\u3193', &['\u4e8c']), ('\u3194', &['\u4e09']), ('\u3195', &['\u56db']), ('\u3196',
- &['\u4e0a']), ('\u3197', &['\u4e2d']), ('\u3198', &['\u4e0b']), ('\u3199', &['\u7532']),
- ('\u319a', &['\u4e59']), ('\u319b', &['\u4e19']), ('\u319c', &['\u4e01']), ('\u319d',
- &['\u5929']), ('\u319e', &['\u5730']), ('\u319f', &['\u4eba']), ('\u3200', &['\x28',
- '\u1100', '\x29']), ('\u3201', &['\x28', '\u1102', '\x29']), ('\u3202', &['\x28', '\u1103',
- '\x29']), ('\u3203', &['\x28', '\u1105', '\x29']), ('\u3204', &['\x28', '\u1106', '\x29']),
- ('\u3205', &['\x28', '\u1107', '\x29']), ('\u3206', &['\x28', '\u1109', '\x29']), ('\u3207',
- &['\x28', '\u110b', '\x29']), ('\u3208', &['\x28', '\u110c', '\x29']), ('\u3209', &['\x28',
- '\u110e', '\x29']), ('\u320a', &['\x28', '\u110f', '\x29']), ('\u320b', &['\x28', '\u1110',
- '\x29']), ('\u320c', &['\x28', '\u1111', '\x29']), ('\u320d', &['\x28', '\u1112', '\x29']),
- ('\u320e', &['\x28', '\u1100', '\u1161', '\x29']), ('\u320f', &['\x28', '\u1102', '\u1161',
- '\x29']), ('\u3210', &['\x28', '\u1103', '\u1161', '\x29']), ('\u3211', &['\x28', '\u1105',
- '\u1161', '\x29']), ('\u3212', &['\x28', '\u1106', '\u1161', '\x29']), ('\u3213', &['\x28',
- '\u1107', '\u1161', '\x29']), ('\u3214', &['\x28', '\u1109', '\u1161', '\x29']), ('\u3215',
- &['\x28', '\u110b', '\u1161', '\x29']), ('\u3216', &['\x28', '\u110c', '\u1161', '\x29']),
- ('\u3217', &['\x28', '\u110e', '\u1161', '\x29']), ('\u3218', &['\x28', '\u110f', '\u1161',
- '\x29']), ('\u3219', &['\x28', '\u1110', '\u1161', '\x29']), ('\u321a', &['\x28', '\u1111',
- '\u1161', '\x29']), ('\u321b', &['\x28', '\u1112', '\u1161', '\x29']), ('\u321c', &['\x28',
- '\u110c', '\u116e', '\x29']), ('\u321d', &['\x28', '\u110b', '\u1169', '\u110c', '\u1165',
- '\u11ab', '\x29']), ('\u321e', &['\x28', '\u110b', '\u1169', '\u1112', '\u116e', '\x29']),
- ('\u3220', &['\x28', '\u4e00', '\x29']), ('\u3221', &['\x28', '\u4e8c', '\x29']), ('\u3222',
- &['\x28', '\u4e09', '\x29']), ('\u3223', &['\x28', '\u56db', '\x29']), ('\u3224', &['\x28',
- '\u4e94', '\x29']), ('\u3225', &['\x28', '\u516d', '\x29']), ('\u3226', &['\x28', '\u4e03',
- '\x29']), ('\u3227', &['\x28', '\u516b', '\x29']), ('\u3228', &['\x28', '\u4e5d', '\x29']),
- ('\u3229', &['\x28', '\u5341', '\x29']), ('\u322a', &['\x28', '\u6708', '\x29']), ('\u322b',
- &['\x28', '\u706b', '\x29']), ('\u322c', &['\x28', '\u6c34', '\x29']), ('\u322d', &['\x28',
- '\u6728', '\x29']), ('\u322e', &['\x28', '\u91d1', '\x29']), ('\u322f', &['\x28', '\u571f',
- '\x29']), ('\u3230', &['\x28', '\u65e5', '\x29']), ('\u3231', &['\x28', '\u682a', '\x29']),
- ('\u3232', &['\x28', '\u6709', '\x29']), ('\u3233', &['\x28', '\u793e', '\x29']), ('\u3234',
- &['\x28', '\u540d', '\x29']), ('\u3235', &['\x28', '\u7279', '\x29']), ('\u3236', &['\x28',
- '\u8ca1', '\x29']), ('\u3237', &['\x28', '\u795d', '\x29']), ('\u3238', &['\x28', '\u52b4',
- '\x29']), ('\u3239', &['\x28', '\u4ee3', '\x29']), ('\u323a', &['\x28', '\u547c', '\x29']),
- ('\u323b', &['\x28', '\u5b66', '\x29']), ('\u323c', &['\x28', '\u76e3', '\x29']), ('\u323d',
- &['\x28', '\u4f01', '\x29']), ('\u323e', &['\x28', '\u8cc7', '\x29']), ('\u323f', &['\x28',
- '\u5354', '\x29']), ('\u3240', &['\x28', '\u796d', '\x29']), ('\u3241', &['\x28', '\u4f11',
- '\x29']), ('\u3242', &['\x28', '\u81ea', '\x29']), ('\u3243', &['\x28', '\u81f3', '\x29']),
- ('\u3244', &['\u554f']), ('\u3245', &['\u5e7c']), ('\u3246', &['\u6587']), ('\u3247',
- &['\u7b8f']), ('\u3250', &['\x50', '\x54', '\x45']), ('\u3251', &['\x32', '\x31']),
- ('\u3252', &['\x32', '\x32']), ('\u3253', &['\x32', '\x33']), ('\u3254', &['\x32', '\x34']),
- ('\u3255', &['\x32', '\x35']), ('\u3256', &['\x32', '\x36']), ('\u3257', &['\x32', '\x37']),
- ('\u3258', &['\x32', '\x38']), ('\u3259', &['\x32', '\x39']), ('\u325a', &['\x33', '\x30']),
- ('\u325b', &['\x33', '\x31']), ('\u325c', &['\x33', '\x32']), ('\u325d', &['\x33', '\x33']),
- ('\u325e', &['\x33', '\x34']), ('\u325f', &['\x33', '\x35']), ('\u3260', &['\u1100']),
- ('\u3261', &['\u1102']), ('\u3262', &['\u1103']), ('\u3263', &['\u1105']), ('\u3264',
- &['\u1106']), ('\u3265', &['\u1107']), ('\u3266', &['\u1109']), ('\u3267', &['\u110b']),
- ('\u3268', &['\u110c']), ('\u3269', &['\u110e']), ('\u326a', &['\u110f']), ('\u326b',
- &['\u1110']), ('\u326c', &['\u1111']), ('\u326d', &['\u1112']), ('\u326e', &['\u1100',
- '\u1161']), ('\u326f', &['\u1102', '\u1161']), ('\u3270', &['\u1103', '\u1161']), ('\u3271',
- &['\u1105', '\u1161']), ('\u3272', &['\u1106', '\u1161']), ('\u3273', &['\u1107',
- '\u1161']), ('\u3274', &['\u1109', '\u1161']), ('\u3275', &['\u110b', '\u1161']), ('\u3276',
- &['\u110c', '\u1161']), ('\u3277', &['\u110e', '\u1161']), ('\u3278', &['\u110f',
- '\u1161']), ('\u3279', &['\u1110', '\u1161']), ('\u327a', &['\u1111', '\u1161']), ('\u327b',
- &['\u1112', '\u1161']), ('\u327c', &['\u110e', '\u1161', '\u11b7', '\u1100', '\u1169']),
- ('\u327d', &['\u110c', '\u116e', '\u110b', '\u1174']), ('\u327e', &['\u110b', '\u116e']),
- ('\u3280', &['\u4e00']), ('\u3281', &['\u4e8c']), ('\u3282', &['\u4e09']), ('\u3283',
- &['\u56db']), ('\u3284', &['\u4e94']), ('\u3285', &['\u516d']), ('\u3286', &['\u4e03']),
- ('\u3287', &['\u516b']), ('\u3288', &['\u4e5d']), ('\u3289', &['\u5341']), ('\u328a',
- &['\u6708']), ('\u328b', &['\u706b']), ('\u328c', &['\u6c34']), ('\u328d', &['\u6728']),
- ('\u328e', &['\u91d1']), ('\u328f', &['\u571f']), ('\u3290', &['\u65e5']), ('\u3291',
- &['\u682a']), ('\u3292', &['\u6709']), ('\u3293', &['\u793e']), ('\u3294', &['\u540d']),
- ('\u3295', &['\u7279']), ('\u3296', &['\u8ca1']), ('\u3297', &['\u795d']), ('\u3298',
- &['\u52b4']), ('\u3299', &['\u79d8']), ('\u329a', &['\u7537']), ('\u329b', &['\u5973']),
- ('\u329c', &['\u9069']), ('\u329d', &['\u512a']), ('\u329e', &['\u5370']), ('\u329f',
- &['\u6ce8']), ('\u32a0', &['\u9805']), ('\u32a1', &['\u4f11']), ('\u32a2', &['\u5199']),
- ('\u32a3', &['\u6b63']), ('\u32a4', &['\u4e0a']), ('\u32a5', &['\u4e2d']), ('\u32a6',
- &['\u4e0b']), ('\u32a7', &['\u5de6']), ('\u32a8', &['\u53f3']), ('\u32a9', &['\u533b']),
- ('\u32aa', &['\u5b97']), ('\u32ab', &['\u5b66']), ('\u32ac', &['\u76e3']), ('\u32ad',
- &['\u4f01']), ('\u32ae', &['\u8cc7']), ('\u32af', &['\u5354']), ('\u32b0', &['\u591c']),
- ('\u32b1', &['\x33', '\x36']), ('\u32b2', &['\x33', '\x37']), ('\u32b3', &['\x33', '\x38']),
- ('\u32b4', &['\x33', '\x39']), ('\u32b5', &['\x34', '\x30']), ('\u32b6', &['\x34', '\x31']),
- ('\u32b7', &['\x34', '\x32']), ('\u32b8', &['\x34', '\x33']), ('\u32b9', &['\x34', '\x34']),
- ('\u32ba', &['\x34', '\x35']), ('\u32bb', &['\x34', '\x36']), ('\u32bc', &['\x34', '\x37']),
- ('\u32bd', &['\x34', '\x38']), ('\u32be', &['\x34', '\x39']), ('\u32bf', &['\x35', '\x30']),
- ('\u32c0', &['\x31', '\u6708']), ('\u32c1', &['\x32', '\u6708']), ('\u32c2', &['\x33',
- '\u6708']), ('\u32c3', &['\x34', '\u6708']), ('\u32c4', &['\x35', '\u6708']), ('\u32c5',
- &['\x36', '\u6708']), ('\u32c6', &['\x37', '\u6708']), ('\u32c7', &['\x38', '\u6708']),
- ('\u32c8', &['\x39', '\u6708']), ('\u32c9', &['\x31', '\x30', '\u6708']), ('\u32ca',
- &['\x31', '\x31', '\u6708']), ('\u32cb', &['\x31', '\x32', '\u6708']), ('\u32cc', &['\x48',
- '\x67']), ('\u32cd', &['\x65', '\x72', '\x67']), ('\u32ce', &['\x65', '\x56']), ('\u32cf',
- &['\x4c', '\x54', '\x44']), ('\u32d0', &['\u30a2']), ('\u32d1', &['\u30a4']), ('\u32d2',
- &['\u30a6']), ('\u32d3', &['\u30a8']), ('\u32d4', &['\u30aa']), ('\u32d5', &['\u30ab']),
- ('\u32d6', &['\u30ad']), ('\u32d7', &['\u30af']), ('\u32d8', &['\u30b1']), ('\u32d9',
- &['\u30b3']), ('\u32da', &['\u30b5']), ('\u32db', &['\u30b7']), ('\u32dc', &['\u30b9']),
- ('\u32dd', &['\u30bb']), ('\u32de', &['\u30bd']), ('\u32df', &['\u30bf']), ('\u32e0',
- &['\u30c1']), ('\u32e1', &['\u30c4']), ('\u32e2', &['\u30c6']), ('\u32e3', &['\u30c8']),
- ('\u32e4', &['\u30ca']), ('\u32e5', &['\u30cb']), ('\u32e6', &['\u30cc']), ('\u32e7',
- &['\u30cd']), ('\u32e8', &['\u30ce']), ('\u32e9', &['\u30cf']), ('\u32ea', &['\u30d2']),
- ('\u32eb', &['\u30d5']), ('\u32ec', &['\u30d8']), ('\u32ed', &['\u30db']), ('\u32ee',
- &['\u30de']), ('\u32ef', &['\u30df']), ('\u32f0', &['\u30e0']), ('\u32f1', &['\u30e1']),
- ('\u32f2', &['\u30e2']), ('\u32f3', &['\u30e4']), ('\u32f4', &['\u30e6']), ('\u32f5',
- &['\u30e8']), ('\u32f6', &['\u30e9']), ('\u32f7', &['\u30ea']), ('\u32f8', &['\u30eb']),
- ('\u32f9', &['\u30ec']), ('\u32fa', &['\u30ed']), ('\u32fb', &['\u30ef']), ('\u32fc',
- &['\u30f0']), ('\u32fd', &['\u30f1']), ('\u32fe', &['\u30f2']), ('\u3300', &['\u30a2',
- '\u30d1', '\u30fc', '\u30c8']), ('\u3301', &['\u30a2', '\u30eb', '\u30d5', '\u30a1']),
- ('\u3302', &['\u30a2', '\u30f3', '\u30da', '\u30a2']), ('\u3303', &['\u30a2', '\u30fc',
- '\u30eb']), ('\u3304', &['\u30a4', '\u30cb', '\u30f3', '\u30b0']), ('\u3305', &['\u30a4',
- '\u30f3', '\u30c1']), ('\u3306', &['\u30a6', '\u30a9', '\u30f3']), ('\u3307', &['\u30a8',
- '\u30b9', '\u30af', '\u30fc', '\u30c9']), ('\u3308', &['\u30a8', '\u30fc', '\u30ab',
- '\u30fc']), ('\u3309', &['\u30aa', '\u30f3', '\u30b9']), ('\u330a', &['\u30aa', '\u30fc',
- '\u30e0']), ('\u330b', &['\u30ab', '\u30a4', '\u30ea']), ('\u330c', &['\u30ab', '\u30e9',
- '\u30c3', '\u30c8']), ('\u330d', &['\u30ab', '\u30ed', '\u30ea', '\u30fc']), ('\u330e',
- &['\u30ac', '\u30ed', '\u30f3']), ('\u330f', &['\u30ac', '\u30f3', '\u30de']), ('\u3310',
- &['\u30ae', '\u30ac']), ('\u3311', &['\u30ae', '\u30cb', '\u30fc']), ('\u3312', &['\u30ad',
- '\u30e5', '\u30ea', '\u30fc']), ('\u3313', &['\u30ae', '\u30eb', '\u30c0', '\u30fc']),
- ('\u3314', &['\u30ad', '\u30ed']), ('\u3315', &['\u30ad', '\u30ed', '\u30b0', '\u30e9',
- '\u30e0']), ('\u3316', &['\u30ad', '\u30ed', '\u30e1', '\u30fc', '\u30c8', '\u30eb']),
- ('\u3317', &['\u30ad', '\u30ed', '\u30ef', '\u30c3', '\u30c8']), ('\u3318', &['\u30b0',
- '\u30e9', '\u30e0']), ('\u3319', &['\u30b0', '\u30e9', '\u30e0', '\u30c8', '\u30f3']),
- ('\u331a', &['\u30af', '\u30eb', '\u30bc', '\u30a4', '\u30ed']), ('\u331b', &['\u30af',
- '\u30ed', '\u30fc', '\u30cd']), ('\u331c', &['\u30b1', '\u30fc', '\u30b9']), ('\u331d',
- &['\u30b3', '\u30eb', '\u30ca']), ('\u331e', &['\u30b3', '\u30fc', '\u30dd']), ('\u331f',
- &['\u30b5', '\u30a4', '\u30af', '\u30eb']), ('\u3320', &['\u30b5', '\u30f3', '\u30c1',
- '\u30fc', '\u30e0']), ('\u3321', &['\u30b7', '\u30ea', '\u30f3', '\u30b0']), ('\u3322',
- &['\u30bb', '\u30f3', '\u30c1']), ('\u3323', &['\u30bb', '\u30f3', '\u30c8']), ('\u3324',
- &['\u30c0', '\u30fc', '\u30b9']), ('\u3325', &['\u30c7', '\u30b7']), ('\u3326', &['\u30c9',
- '\u30eb']), ('\u3327', &['\u30c8', '\u30f3']), ('\u3328', &['\u30ca', '\u30ce']), ('\u3329',
- &['\u30ce', '\u30c3', '\u30c8']), ('\u332a', &['\u30cf', '\u30a4', '\u30c4']), ('\u332b',
- &['\u30d1', '\u30fc', '\u30bb', '\u30f3', '\u30c8']), ('\u332c', &['\u30d1', '\u30fc',
- '\u30c4']), ('\u332d', &['\u30d0', '\u30fc', '\u30ec', '\u30eb']), ('\u332e', &['\u30d4',
- '\u30a2', '\u30b9', '\u30c8', '\u30eb']), ('\u332f', &['\u30d4', '\u30af', '\u30eb']),
- ('\u3330', &['\u30d4', '\u30b3']), ('\u3331', &['\u30d3', '\u30eb']), ('\u3332', &['\u30d5',
- '\u30a1', '\u30e9', '\u30c3', '\u30c9']), ('\u3333', &['\u30d5', '\u30a3', '\u30fc',
- '\u30c8']), ('\u3334', &['\u30d6', '\u30c3', '\u30b7', '\u30a7', '\u30eb']), ('\u3335',
- &['\u30d5', '\u30e9', '\u30f3']), ('\u3336', &['\u30d8', '\u30af', '\u30bf', '\u30fc',
- '\u30eb']), ('\u3337', &['\u30da', '\u30bd']), ('\u3338', &['\u30da', '\u30cb', '\u30d2']),
- ('\u3339', &['\u30d8', '\u30eb', '\u30c4']), ('\u333a', &['\u30da', '\u30f3', '\u30b9']),
- ('\u333b', &['\u30da', '\u30fc', '\u30b8']), ('\u333c', &['\u30d9', '\u30fc', '\u30bf']),
- ('\u333d', &['\u30dd', '\u30a4', '\u30f3', '\u30c8']), ('\u333e', &['\u30dc', '\u30eb',
- '\u30c8']), ('\u333f', &['\u30db', '\u30f3']), ('\u3340', &['\u30dd', '\u30f3', '\u30c9']),
- ('\u3341', &['\u30db', '\u30fc', '\u30eb']), ('\u3342', &['\u30db', '\u30fc', '\u30f3']),
- ('\u3343', &['\u30de', '\u30a4', '\u30af', '\u30ed']), ('\u3344', &['\u30de', '\u30a4',
- '\u30eb']), ('\u3345', &['\u30de', '\u30c3', '\u30cf']), ('\u3346', &['\u30de', '\u30eb',
- '\u30af']), ('\u3347', &['\u30de', '\u30f3', '\u30b7', '\u30e7', '\u30f3']), ('\u3348',
- &['\u30df', '\u30af', '\u30ed', '\u30f3']), ('\u3349', &['\u30df', '\u30ea']), ('\u334a',
- &['\u30df', '\u30ea', '\u30d0', '\u30fc', '\u30eb']), ('\u334b', &['\u30e1', '\u30ac']),
- ('\u334c', &['\u30e1', '\u30ac', '\u30c8', '\u30f3']), ('\u334d', &['\u30e1', '\u30fc',
- '\u30c8', '\u30eb']), ('\u334e', &['\u30e4', '\u30fc', '\u30c9']), ('\u334f', &['\u30e4',
- '\u30fc', '\u30eb']), ('\u3350', &['\u30e6', '\u30a2', '\u30f3']), ('\u3351', &['\u30ea',
- '\u30c3', '\u30c8', '\u30eb']), ('\u3352', &['\u30ea', '\u30e9']), ('\u3353', &['\u30eb',
- '\u30d4', '\u30fc']), ('\u3354', &['\u30eb', '\u30fc', '\u30d6', '\u30eb']), ('\u3355',
- &['\u30ec', '\u30e0']), ('\u3356', &['\u30ec', '\u30f3', '\u30c8', '\u30b2', '\u30f3']),
- ('\u3357', &['\u30ef', '\u30c3', '\u30c8']), ('\u3358', &['\x30', '\u70b9']), ('\u3359',
- &['\x31', '\u70b9']), ('\u335a', &['\x32', '\u70b9']), ('\u335b', &['\x33', '\u70b9']),
- ('\u335c', &['\x34', '\u70b9']), ('\u335d', &['\x35', '\u70b9']), ('\u335e', &['\x36',
- '\u70b9']), ('\u335f', &['\x37', '\u70b9']), ('\u3360', &['\x38', '\u70b9']), ('\u3361',
- &['\x39', '\u70b9']), ('\u3362', &['\x31', '\x30', '\u70b9']), ('\u3363', &['\x31', '\x31',
- '\u70b9']), ('\u3364', &['\x31', '\x32', '\u70b9']), ('\u3365', &['\x31', '\x33',
- '\u70b9']), ('\u3366', &['\x31', '\x34', '\u70b9']), ('\u3367', &['\x31', '\x35',
- '\u70b9']), ('\u3368', &['\x31', '\x36', '\u70b9']), ('\u3369', &['\x31', '\x37',
- '\u70b9']), ('\u336a', &['\x31', '\x38', '\u70b9']), ('\u336b', &['\x31', '\x39',
- '\u70b9']), ('\u336c', &['\x32', '\x30', '\u70b9']), ('\u336d', &['\x32', '\x31',
- '\u70b9']), ('\u336e', &['\x32', '\x32', '\u70b9']), ('\u336f', &['\x32', '\x33',
- '\u70b9']), ('\u3370', &['\x32', '\x34', '\u70b9']), ('\u3371', &['\x68', '\x50', '\x61']),
- ('\u3372', &['\x64', '\x61']), ('\u3373', &['\x41', '\x55']), ('\u3374', &['\x62', '\x61',
- '\x72']), ('\u3375', &['\x6f', '\x56']), ('\u3376', &['\x70', '\x63']), ('\u3377', &['\x64',
- '\x6d']), ('\u3378', &['\x64', '\x6d', '\xb2']), ('\u3379', &['\x64', '\x6d', '\xb3']),
- ('\u337a', &['\x49', '\x55']), ('\u337b', &['\u5e73', '\u6210']), ('\u337c', &['\u662d',
- '\u548c']), ('\u337d', &['\u5927', '\u6b63']), ('\u337e', &['\u660e', '\u6cbb']), ('\u337f',
- &['\u682a', '\u5f0f', '\u4f1a', '\u793e']), ('\u3380', &['\x70', '\x41']), ('\u3381',
- &['\x6e', '\x41']), ('\u3382', &['\u03bc', '\x41']), ('\u3383', &['\x6d', '\x41']),
- ('\u3384', &['\x6b', '\x41']), ('\u3385', &['\x4b', '\x42']), ('\u3386', &['\x4d', '\x42']),
- ('\u3387', &['\x47', '\x42']), ('\u3388', &['\x63', '\x61', '\x6c']), ('\u3389', &['\x6b',
- '\x63', '\x61', '\x6c']), ('\u338a', &['\x70', '\x46']), ('\u338b', &['\x6e', '\x46']),
- ('\u338c', &['\u03bc', '\x46']), ('\u338d', &['\u03bc', '\x67']), ('\u338e', &['\x6d',
- '\x67']), ('\u338f', &['\x6b', '\x67']), ('\u3390', &['\x48', '\x7a']), ('\u3391', &['\x6b',
- '\x48', '\x7a']), ('\u3392', &['\x4d', '\x48', '\x7a']), ('\u3393', &['\x47', '\x48',
- '\x7a']), ('\u3394', &['\x54', '\x48', '\x7a']), ('\u3395', &['\u03bc', '\u2113']),
- ('\u3396', &['\x6d', '\u2113']), ('\u3397', &['\x64', '\u2113']), ('\u3398', &['\x6b',
- '\u2113']), ('\u3399', &['\x66', '\x6d']), ('\u339a', &['\x6e', '\x6d']), ('\u339b',
- &['\u03bc', '\x6d']), ('\u339c', &['\x6d', '\x6d']), ('\u339d', &['\x63', '\x6d']),
- ('\u339e', &['\x6b', '\x6d']), ('\u339f', &['\x6d', '\x6d', '\xb2']), ('\u33a0', &['\x63',
- '\x6d', '\xb2']), ('\u33a1', &['\x6d', '\xb2']), ('\u33a2', &['\x6b', '\x6d', '\xb2']),
- ('\u33a3', &['\x6d', '\x6d', '\xb3']), ('\u33a4', &['\x63', '\x6d', '\xb3']), ('\u33a5',
- &['\x6d', '\xb3']), ('\u33a6', &['\x6b', '\x6d', '\xb3']), ('\u33a7', &['\x6d', '\u2215',
- '\x73']), ('\u33a8', &['\x6d', '\u2215', '\x73', '\xb2']), ('\u33a9', &['\x50', '\x61']),
- ('\u33aa', &['\x6b', '\x50', '\x61']), ('\u33ab', &['\x4d', '\x50', '\x61']), ('\u33ac',
- &['\x47', '\x50', '\x61']), ('\u33ad', &['\x72', '\x61', '\x64']), ('\u33ae', &['\x72',
- '\x61', '\x64', '\u2215', '\x73']), ('\u33af', &['\x72', '\x61', '\x64', '\u2215', '\x73',
- '\xb2']), ('\u33b0', &['\x70', '\x73']), ('\u33b1', &['\x6e', '\x73']), ('\u33b2',
- &['\u03bc', '\x73']), ('\u33b3', &['\x6d', '\x73']), ('\u33b4', &['\x70', '\x56']),
- ('\u33b5', &['\x6e', '\x56']), ('\u33b6', &['\u03bc', '\x56']), ('\u33b7', &['\x6d',
- '\x56']), ('\u33b8', &['\x6b', '\x56']), ('\u33b9', &['\x4d', '\x56']), ('\u33ba', &['\x70',
- '\x57']), ('\u33bb', &['\x6e', '\x57']), ('\u33bc', &['\u03bc', '\x57']), ('\u33bd',
- &['\x6d', '\x57']), ('\u33be', &['\x6b', '\x57']), ('\u33bf', &['\x4d', '\x57']), ('\u33c0',
- &['\x6b', '\u03a9']), ('\u33c1', &['\x4d', '\u03a9']), ('\u33c2', &['\x61', '\x2e', '\x6d',
- '\x2e']), ('\u33c3', &['\x42', '\x71']), ('\u33c4', &['\x63', '\x63']), ('\u33c5', &['\x63',
- '\x64']), ('\u33c6', &['\x43', '\u2215', '\x6b', '\x67']), ('\u33c7', &['\x43', '\x6f',
- '\x2e']), ('\u33c8', &['\x64', '\x42']), ('\u33c9', &['\x47', '\x79']), ('\u33ca', &['\x68',
- '\x61']), ('\u33cb', &['\x48', '\x50']), ('\u33cc', &['\x69', '\x6e']), ('\u33cd', &['\x4b',
- '\x4b']), ('\u33ce', &['\x4b', '\x4d']), ('\u33cf', &['\x6b', '\x74']), ('\u33d0', &['\x6c',
- '\x6d']), ('\u33d1', &['\x6c', '\x6e']), ('\u33d2', &['\x6c', '\x6f', '\x67']), ('\u33d3',
- &['\x6c', '\x78']), ('\u33d4', &['\x6d', '\x62']), ('\u33d5', &['\x6d', '\x69', '\x6c']),
- ('\u33d6', &['\x6d', '\x6f', '\x6c']), ('\u33d7', &['\x50', '\x48']), ('\u33d8', &['\x70',
- '\x2e', '\x6d', '\x2e']), ('\u33d9', &['\x50', '\x50', '\x4d']), ('\u33da', &['\x50',
- '\x52']), ('\u33db', &['\x73', '\x72']), ('\u33dc', &['\x53', '\x76']), ('\u33dd', &['\x57',
- '\x62']), ('\u33de', &['\x56', '\u2215', '\x6d']), ('\u33df', &['\x41', '\u2215', '\x6d']),
- ('\u33e0', &['\x31', '\u65e5']), ('\u33e1', &['\x32', '\u65e5']), ('\u33e2', &['\x33',
- '\u65e5']), ('\u33e3', &['\x34', '\u65e5']), ('\u33e4', &['\x35', '\u65e5']), ('\u33e5',
- &['\x36', '\u65e5']), ('\u33e6', &['\x37', '\u65e5']), ('\u33e7', &['\x38', '\u65e5']),
- ('\u33e8', &['\x39', '\u65e5']), ('\u33e9', &['\x31', '\x30', '\u65e5']), ('\u33ea',
- &['\x31', '\x31', '\u65e5']), ('\u33eb', &['\x31', '\x32', '\u65e5']), ('\u33ec', &['\x31',
- '\x33', '\u65e5']), ('\u33ed', &['\x31', '\x34', '\u65e5']), ('\u33ee', &['\x31', '\x35',
- '\u65e5']), ('\u33ef', &['\x31', '\x36', '\u65e5']), ('\u33f0', &['\x31', '\x37',
- '\u65e5']), ('\u33f1', &['\x31', '\x38', '\u65e5']), ('\u33f2', &['\x31', '\x39',
- '\u65e5']), ('\u33f3', &['\x32', '\x30', '\u65e5']), ('\u33f4', &['\x32', '\x31',
- '\u65e5']), ('\u33f5', &['\x32', '\x32', '\u65e5']), ('\u33f6', &['\x32', '\x33',
- '\u65e5']), ('\u33f7', &['\x32', '\x34', '\u65e5']), ('\u33f8', &['\x32', '\x35',
- '\u65e5']), ('\u33f9', &['\x32', '\x36', '\u65e5']), ('\u33fa', &['\x32', '\x37',
- '\u65e5']), ('\u33fb', &['\x32', '\x38', '\u65e5']), ('\u33fc', &['\x32', '\x39',
- '\u65e5']), ('\u33fd', &['\x33', '\x30', '\u65e5']), ('\u33fe', &['\x33', '\x31',
- '\u65e5']), ('\u33ff', &['\x67', '\x61', '\x6c']), ('\ua770', &['\ua76f']), ('\ua7f8',
- &['\u0126']), ('\ua7f9', &['\u0153']), ('\ufb00', &['\x66', '\x66']), ('\ufb01', &['\x66',
- '\x69']), ('\ufb02', &['\x66', '\x6c']), ('\ufb03', &['\x66', '\x66', '\x69']), ('\ufb04',
- &['\x66', '\x66', '\x6c']), ('\ufb05', &['\u017f', '\x74']), ('\ufb06', &['\x73', '\x74']),
- ('\ufb13', &['\u0574', '\u0576']), ('\ufb14', &['\u0574', '\u0565']), ('\ufb15', &['\u0574',
- '\u056b']), ('\ufb16', &['\u057e', '\u0576']), ('\ufb17', &['\u0574', '\u056d']), ('\ufb20',
- &['\u05e2']), ('\ufb21', &['\u05d0']), ('\ufb22', &['\u05d3']), ('\ufb23', &['\u05d4']),
- ('\ufb24', &['\u05db']), ('\ufb25', &['\u05dc']), ('\ufb26', &['\u05dd']), ('\ufb27',
- &['\u05e8']), ('\ufb28', &['\u05ea']), ('\ufb29', &['\x2b']), ('\ufb4f', &['\u05d0',
- '\u05dc']), ('\ufb50', &['\u0671']), ('\ufb51', &['\u0671']), ('\ufb52', &['\u067b']),
- ('\ufb53', &['\u067b']), ('\ufb54', &['\u067b']), ('\ufb55', &['\u067b']), ('\ufb56',
- &['\u067e']), ('\ufb57', &['\u067e']), ('\ufb58', &['\u067e']), ('\ufb59', &['\u067e']),
- ('\ufb5a', &['\u0680']), ('\ufb5b', &['\u0680']), ('\ufb5c', &['\u0680']), ('\ufb5d',
- &['\u0680']), ('\ufb5e', &['\u067a']), ('\ufb5f', &['\u067a']), ('\ufb60', &['\u067a']),
- ('\ufb61', &['\u067a']), ('\ufb62', &['\u067f']), ('\ufb63', &['\u067f']), ('\ufb64',
- &['\u067f']), ('\ufb65', &['\u067f']), ('\ufb66', &['\u0679']), ('\ufb67', &['\u0679']),
- ('\ufb68', &['\u0679']), ('\ufb69', &['\u0679']), ('\ufb6a', &['\u06a4']), ('\ufb6b',
- &['\u06a4']), ('\ufb6c', &['\u06a4']), ('\ufb6d', &['\u06a4']), ('\ufb6e', &['\u06a6']),
- ('\ufb6f', &['\u06a6']), ('\ufb70', &['\u06a6']), ('\ufb71', &['\u06a6']), ('\ufb72',
- &['\u0684']), ('\ufb73', &['\u0684']), ('\ufb74', &['\u0684']), ('\ufb75', &['\u0684']),
- ('\ufb76', &['\u0683']), ('\ufb77', &['\u0683']), ('\ufb78', &['\u0683']), ('\ufb79',
- &['\u0683']), ('\ufb7a', &['\u0686']), ('\ufb7b', &['\u0686']), ('\ufb7c', &['\u0686']),
- ('\ufb7d', &['\u0686']), ('\ufb7e', &['\u0687']), ('\ufb7f', &['\u0687']), ('\ufb80',
- &['\u0687']), ('\ufb81', &['\u0687']), ('\ufb82', &['\u068d']), ('\ufb83', &['\u068d']),
- ('\ufb84', &['\u068c']), ('\ufb85', &['\u068c']), ('\ufb86', &['\u068e']), ('\ufb87',
- &['\u068e']), ('\ufb88', &['\u0688']), ('\ufb89', &['\u0688']), ('\ufb8a', &['\u0698']),
- ('\ufb8b', &['\u0698']), ('\ufb8c', &['\u0691']), ('\ufb8d', &['\u0691']), ('\ufb8e',
- &['\u06a9']), ('\ufb8f', &['\u06a9']), ('\ufb90', &['\u06a9']), ('\ufb91', &['\u06a9']),
- ('\ufb92', &['\u06af']), ('\ufb93', &['\u06af']), ('\ufb94', &['\u06af']), ('\ufb95',
- &['\u06af']), ('\ufb96', &['\u06b3']), ('\ufb97', &['\u06b3']), ('\ufb98', &['\u06b3']),
- ('\ufb99', &['\u06b3']), ('\ufb9a', &['\u06b1']), ('\ufb9b', &['\u06b1']), ('\ufb9c',
- &['\u06b1']), ('\ufb9d', &['\u06b1']), ('\ufb9e', &['\u06ba']), ('\ufb9f', &['\u06ba']),
- ('\ufba0', &['\u06bb']), ('\ufba1', &['\u06bb']), ('\ufba2', &['\u06bb']), ('\ufba3',
- &['\u06bb']), ('\ufba4', &['\u06c0']), ('\ufba5', &['\u06c0']), ('\ufba6', &['\u06c1']),
- ('\ufba7', &['\u06c1']), ('\ufba8', &['\u06c1']), ('\ufba9', &['\u06c1']), ('\ufbaa',
- &['\u06be']), ('\ufbab', &['\u06be']), ('\ufbac', &['\u06be']), ('\ufbad', &['\u06be']),
- ('\ufbae', &['\u06d2']), ('\ufbaf', &['\u06d2']), ('\ufbb0', &['\u06d3']), ('\ufbb1',
- &['\u06d3']), ('\ufbd3', &['\u06ad']), ('\ufbd4', &['\u06ad']), ('\ufbd5', &['\u06ad']),
- ('\ufbd6', &['\u06ad']), ('\ufbd7', &['\u06c7']), ('\ufbd8', &['\u06c7']), ('\ufbd9',
- &['\u06c6']), ('\ufbda', &['\u06c6']), ('\ufbdb', &['\u06c8']), ('\ufbdc', &['\u06c8']),
- ('\ufbdd', &['\u0677']), ('\ufbde', &['\u06cb']), ('\ufbdf', &['\u06cb']), ('\ufbe0',
- &['\u06c5']), ('\ufbe1', &['\u06c5']), ('\ufbe2', &['\u06c9']), ('\ufbe3', &['\u06c9']),
- ('\ufbe4', &['\u06d0']), ('\ufbe5', &['\u06d0']), ('\ufbe6', &['\u06d0']), ('\ufbe7',
- &['\u06d0']), ('\ufbe8', &['\u0649']), ('\ufbe9', &['\u0649']), ('\ufbea', &['\u0626',
- '\u0627']), ('\ufbeb', &['\u0626', '\u0627']), ('\ufbec', &['\u0626', '\u06d5']), ('\ufbed',
- &['\u0626', '\u06d5']), ('\ufbee', &['\u0626', '\u0648']), ('\ufbef', &['\u0626',
- '\u0648']), ('\ufbf0', &['\u0626', '\u06c7']), ('\ufbf1', &['\u0626', '\u06c7']), ('\ufbf2',
- &['\u0626', '\u06c6']), ('\ufbf3', &['\u0626', '\u06c6']), ('\ufbf4', &['\u0626',
- '\u06c8']), ('\ufbf5', &['\u0626', '\u06c8']), ('\ufbf6', &['\u0626', '\u06d0']), ('\ufbf7',
- &['\u0626', '\u06d0']), ('\ufbf8', &['\u0626', '\u06d0']), ('\ufbf9', &['\u0626',
- '\u0649']), ('\ufbfa', &['\u0626', '\u0649']), ('\ufbfb', &['\u0626', '\u0649']), ('\ufbfc',
- &['\u06cc']), ('\ufbfd', &['\u06cc']), ('\ufbfe', &['\u06cc']), ('\ufbff', &['\u06cc']),
- ('\ufc00', &['\u0626', '\u062c']), ('\ufc01', &['\u0626', '\u062d']), ('\ufc02', &['\u0626',
- '\u0645']), ('\ufc03', &['\u0626', '\u0649']), ('\ufc04', &['\u0626', '\u064a']), ('\ufc05',
- &['\u0628', '\u062c']), ('\ufc06', &['\u0628', '\u062d']), ('\ufc07', &['\u0628',
- '\u062e']), ('\ufc08', &['\u0628', '\u0645']), ('\ufc09', &['\u0628', '\u0649']), ('\ufc0a',
- &['\u0628', '\u064a']), ('\ufc0b', &['\u062a', '\u062c']), ('\ufc0c', &['\u062a',
- '\u062d']), ('\ufc0d', &['\u062a', '\u062e']), ('\ufc0e', &['\u062a', '\u0645']), ('\ufc0f',
- &['\u062a', '\u0649']), ('\ufc10', &['\u062a', '\u064a']), ('\ufc11', &['\u062b',
- '\u062c']), ('\ufc12', &['\u062b', '\u0645']), ('\ufc13', &['\u062b', '\u0649']), ('\ufc14',
- &['\u062b', '\u064a']), ('\ufc15', &['\u062c', '\u062d']), ('\ufc16', &['\u062c',
- '\u0645']), ('\ufc17', &['\u062d', '\u062c']), ('\ufc18', &['\u062d', '\u0645']), ('\ufc19',
- &['\u062e', '\u062c']), ('\ufc1a', &['\u062e', '\u062d']), ('\ufc1b', &['\u062e',
- '\u0645']), ('\ufc1c', &['\u0633', '\u062c']), ('\ufc1d', &['\u0633', '\u062d']), ('\ufc1e',
- &['\u0633', '\u062e']), ('\ufc1f', &['\u0633', '\u0645']), ('\ufc20', &['\u0635',
- '\u062d']), ('\ufc21', &['\u0635', '\u0645']), ('\ufc22', &['\u0636', '\u062c']), ('\ufc23',
- &['\u0636', '\u062d']), ('\ufc24', &['\u0636', '\u062e']), ('\ufc25', &['\u0636',
- '\u0645']), ('\ufc26', &['\u0637', '\u062d']), ('\ufc27', &['\u0637', '\u0645']), ('\ufc28',
- &['\u0638', '\u0645']), ('\ufc29', &['\u0639', '\u062c']), ('\ufc2a', &['\u0639',
- '\u0645']), ('\ufc2b', &['\u063a', '\u062c']), ('\ufc2c', &['\u063a', '\u0645']), ('\ufc2d',
- &['\u0641', '\u062c']), ('\ufc2e', &['\u0641', '\u062d']), ('\ufc2f', &['\u0641',
- '\u062e']), ('\ufc30', &['\u0641', '\u0645']), ('\ufc31', &['\u0641', '\u0649']), ('\ufc32',
- &['\u0641', '\u064a']), ('\ufc33', &['\u0642', '\u062d']), ('\ufc34', &['\u0642',
- '\u0645']), ('\ufc35', &['\u0642', '\u0649']), ('\ufc36', &['\u0642', '\u064a']), ('\ufc37',
- &['\u0643', '\u0627']), ('\ufc38', &['\u0643', '\u062c']), ('\ufc39', &['\u0643',
- '\u062d']), ('\ufc3a', &['\u0643', '\u062e']), ('\ufc3b', &['\u0643', '\u0644']), ('\ufc3c',
- &['\u0643', '\u0645']), ('\ufc3d', &['\u0643', '\u0649']), ('\ufc3e', &['\u0643',
- '\u064a']), ('\ufc3f', &['\u0644', '\u062c']), ('\ufc40', &['\u0644', '\u062d']), ('\ufc41',
- &['\u0644', '\u062e']), ('\ufc42', &['\u0644', '\u0645']), ('\ufc43', &['\u0644',
- '\u0649']), ('\ufc44', &['\u0644', '\u064a']), ('\ufc45', &['\u0645', '\u062c']), ('\ufc46',
- &['\u0645', '\u062d']), ('\ufc47', &['\u0645', '\u062e']), ('\ufc48', &['\u0645',
- '\u0645']), ('\ufc49', &['\u0645', '\u0649']), ('\ufc4a', &['\u0645', '\u064a']), ('\ufc4b',
- &['\u0646', '\u062c']), ('\ufc4c', &['\u0646', '\u062d']), ('\ufc4d', &['\u0646',
- '\u062e']), ('\ufc4e', &['\u0646', '\u0645']), ('\ufc4f', &['\u0646', '\u0649']), ('\ufc50',
- &['\u0646', '\u064a']), ('\ufc51', &['\u0647', '\u062c']), ('\ufc52', &['\u0647',
- '\u0645']), ('\ufc53', &['\u0647', '\u0649']), ('\ufc54', &['\u0647', '\u064a']), ('\ufc55',
- &['\u064a', '\u062c']), ('\ufc56', &['\u064a', '\u062d']), ('\ufc57', &['\u064a',
- '\u062e']), ('\ufc58', &['\u064a', '\u0645']), ('\ufc59', &['\u064a', '\u0649']), ('\ufc5a',
- &['\u064a', '\u064a']), ('\ufc5b', &['\u0630', '\u0670']), ('\ufc5c', &['\u0631',
- '\u0670']), ('\ufc5d', &['\u0649', '\u0670']), ('\ufc5e', &['\x20', '\u064c', '\u0651']),
- ('\ufc5f', &['\x20', '\u064d', '\u0651']), ('\ufc60', &['\x20', '\u064e', '\u0651']),
- ('\ufc61', &['\x20', '\u064f', '\u0651']), ('\ufc62', &['\x20', '\u0650', '\u0651']),
- ('\ufc63', &['\x20', '\u0651', '\u0670']), ('\ufc64', &['\u0626', '\u0631']), ('\ufc65',
- &['\u0626', '\u0632']), ('\ufc66', &['\u0626', '\u0645']), ('\ufc67', &['\u0626',
- '\u0646']), ('\ufc68', &['\u0626', '\u0649']), ('\ufc69', &['\u0626', '\u064a']), ('\ufc6a',
- &['\u0628', '\u0631']), ('\ufc6b', &['\u0628', '\u0632']), ('\ufc6c', &['\u0628',
- '\u0645']), ('\ufc6d', &['\u0628', '\u0646']), ('\ufc6e', &['\u0628', '\u0649']), ('\ufc6f',
- &['\u0628', '\u064a']), ('\ufc70', &['\u062a', '\u0631']), ('\ufc71', &['\u062a',
- '\u0632']), ('\ufc72', &['\u062a', '\u0645']), ('\ufc73', &['\u062a', '\u0646']), ('\ufc74',
- &['\u062a', '\u0649']), ('\ufc75', &['\u062a', '\u064a']), ('\ufc76', &['\u062b',
- '\u0631']), ('\ufc77', &['\u062b', '\u0632']), ('\ufc78', &['\u062b', '\u0645']), ('\ufc79',
- &['\u062b', '\u0646']), ('\ufc7a', &['\u062b', '\u0649']), ('\ufc7b', &['\u062b',
- '\u064a']), ('\ufc7c', &['\u0641', '\u0649']), ('\ufc7d', &['\u0641', '\u064a']), ('\ufc7e',
- &['\u0642', '\u0649']), ('\ufc7f', &['\u0642', '\u064a']), ('\ufc80', &['\u0643',
- '\u0627']), ('\ufc81', &['\u0643', '\u0644']), ('\ufc82', &['\u0643', '\u0645']), ('\ufc83',
- &['\u0643', '\u0649']), ('\ufc84', &['\u0643', '\u064a']), ('\ufc85', &['\u0644',
- '\u0645']), ('\ufc86', &['\u0644', '\u0649']), ('\ufc87', &['\u0644', '\u064a']), ('\ufc88',
- &['\u0645', '\u0627']), ('\ufc89', &['\u0645', '\u0645']), ('\ufc8a', &['\u0646',
- '\u0631']), ('\ufc8b', &['\u0646', '\u0632']), ('\ufc8c', &['\u0646', '\u0645']), ('\ufc8d',
- &['\u0646', '\u0646']), ('\ufc8e', &['\u0646', '\u0649']), ('\ufc8f', &['\u0646',
- '\u064a']), ('\ufc90', &['\u0649', '\u0670']), ('\ufc91', &['\u064a', '\u0631']), ('\ufc92',
- &['\u064a', '\u0632']), ('\ufc93', &['\u064a', '\u0645']), ('\ufc94', &['\u064a',
- '\u0646']), ('\ufc95', &['\u064a', '\u0649']), ('\ufc96', &['\u064a', '\u064a']), ('\ufc97',
- &['\u0626', '\u062c']), ('\ufc98', &['\u0626', '\u062d']), ('\ufc99', &['\u0626',
- '\u062e']), ('\ufc9a', &['\u0626', '\u0645']), ('\ufc9b', &['\u0626', '\u0647']), ('\ufc9c',
- &['\u0628', '\u062c']), ('\ufc9d', &['\u0628', '\u062d']), ('\ufc9e', &['\u0628',
- '\u062e']), ('\ufc9f', &['\u0628', '\u0645']), ('\ufca0', &['\u0628', '\u0647']), ('\ufca1',
- &['\u062a', '\u062c']), ('\ufca2', &['\u062a', '\u062d']), ('\ufca3', &['\u062a',
- '\u062e']), ('\ufca4', &['\u062a', '\u0645']), ('\ufca5', &['\u062a', '\u0647']), ('\ufca6',
- &['\u062b', '\u0645']), ('\ufca7', &['\u062c', '\u062d']), ('\ufca8', &['\u062c',
- '\u0645']), ('\ufca9', &['\u062d', '\u062c']), ('\ufcaa', &['\u062d', '\u0645']), ('\ufcab',
- &['\u062e', '\u062c']), ('\ufcac', &['\u062e', '\u0645']), ('\ufcad', &['\u0633',
- '\u062c']), ('\ufcae', &['\u0633', '\u062d']), ('\ufcaf', &['\u0633', '\u062e']), ('\ufcb0',
- &['\u0633', '\u0645']), ('\ufcb1', &['\u0635', '\u062d']), ('\ufcb2', &['\u0635',
- '\u062e']), ('\ufcb3', &['\u0635', '\u0645']), ('\ufcb4', &['\u0636', '\u062c']), ('\ufcb5',
- &['\u0636', '\u062d']), ('\ufcb6', &['\u0636', '\u062e']), ('\ufcb7', &['\u0636',
- '\u0645']), ('\ufcb8', &['\u0637', '\u062d']), ('\ufcb9', &['\u0638', '\u0645']), ('\ufcba',
- &['\u0639', '\u062c']), ('\ufcbb', &['\u0639', '\u0645']), ('\ufcbc', &['\u063a',
- '\u062c']), ('\ufcbd', &['\u063a', '\u0645']), ('\ufcbe', &['\u0641', '\u062c']), ('\ufcbf',
- &['\u0641', '\u062d']), ('\ufcc0', &['\u0641', '\u062e']), ('\ufcc1', &['\u0641',
- '\u0645']), ('\ufcc2', &['\u0642', '\u062d']), ('\ufcc3', &['\u0642', '\u0645']), ('\ufcc4',
- &['\u0643', '\u062c']), ('\ufcc5', &['\u0643', '\u062d']), ('\ufcc6', &['\u0643',
- '\u062e']), ('\ufcc7', &['\u0643', '\u0644']), ('\ufcc8', &['\u0643', '\u0645']), ('\ufcc9',
- &['\u0644', '\u062c']), ('\ufcca', &['\u0644', '\u062d']), ('\ufccb', &['\u0644',
- '\u062e']), ('\ufccc', &['\u0644', '\u0645']), ('\ufccd', &['\u0644', '\u0647']), ('\ufcce',
- &['\u0645', '\u062c']), ('\ufccf', &['\u0645', '\u062d']), ('\ufcd0', &['\u0645',
- '\u062e']), ('\ufcd1', &['\u0645', '\u0645']), ('\ufcd2', &['\u0646', '\u062c']), ('\ufcd3',
- &['\u0646', '\u062d']), ('\ufcd4', &['\u0646', '\u062e']), ('\ufcd5', &['\u0646',
- '\u0645']), ('\ufcd6', &['\u0646', '\u0647']), ('\ufcd7', &['\u0647', '\u062c']), ('\ufcd8',
- &['\u0647', '\u0645']), ('\ufcd9', &['\u0647', '\u0670']), ('\ufcda', &['\u064a',
- '\u062c']), ('\ufcdb', &['\u064a', '\u062d']), ('\ufcdc', &['\u064a', '\u062e']), ('\ufcdd',
- &['\u064a', '\u0645']), ('\ufcde', &['\u064a', '\u0647']), ('\ufcdf', &['\u0626',
- '\u0645']), ('\ufce0', &['\u0626', '\u0647']), ('\ufce1', &['\u0628', '\u0645']), ('\ufce2',
- &['\u0628', '\u0647']), ('\ufce3', &['\u062a', '\u0645']), ('\ufce4', &['\u062a',
- '\u0647']), ('\ufce5', &['\u062b', '\u0645']), ('\ufce6', &['\u062b', '\u0647']), ('\ufce7',
- &['\u0633', '\u0645']), ('\ufce8', &['\u0633', '\u0647']), ('\ufce9', &['\u0634',
- '\u0645']), ('\ufcea', &['\u0634', '\u0647']), ('\ufceb', &['\u0643', '\u0644']), ('\ufcec',
- &['\u0643', '\u0645']), ('\ufced', &['\u0644', '\u0645']), ('\ufcee', &['\u0646',
- '\u0645']), ('\ufcef', &['\u0646', '\u0647']), ('\ufcf0', &['\u064a', '\u0645']), ('\ufcf1',
- &['\u064a', '\u0647']), ('\ufcf2', &['\u0640', '\u064e', '\u0651']), ('\ufcf3', &['\u0640',
- '\u064f', '\u0651']), ('\ufcf4', &['\u0640', '\u0650', '\u0651']), ('\ufcf5', &['\u0637',
- '\u0649']), ('\ufcf6', &['\u0637', '\u064a']), ('\ufcf7', &['\u0639', '\u0649']), ('\ufcf8',
- &['\u0639', '\u064a']), ('\ufcf9', &['\u063a', '\u0649']), ('\ufcfa', &['\u063a',
- '\u064a']), ('\ufcfb', &['\u0633', '\u0649']), ('\ufcfc', &['\u0633', '\u064a']), ('\ufcfd',
- &['\u0634', '\u0649']), ('\ufcfe', &['\u0634', '\u064a']), ('\ufcff', &['\u062d',
- '\u0649']), ('\ufd00', &['\u062d', '\u064a']), ('\ufd01', &['\u062c', '\u0649']), ('\ufd02',
- &['\u062c', '\u064a']), ('\ufd03', &['\u062e', '\u0649']), ('\ufd04', &['\u062e',
- '\u064a']), ('\ufd05', &['\u0635', '\u0649']), ('\ufd06', &['\u0635', '\u064a']), ('\ufd07',
- &['\u0636', '\u0649']), ('\ufd08', &['\u0636', '\u064a']), ('\ufd09', &['\u0634',
- '\u062c']), ('\ufd0a', &['\u0634', '\u062d']), ('\ufd0b', &['\u0634', '\u062e']), ('\ufd0c',
- &['\u0634', '\u0645']), ('\ufd0d', &['\u0634', '\u0631']), ('\ufd0e', &['\u0633',
- '\u0631']), ('\ufd0f', &['\u0635', '\u0631']), ('\ufd10', &['\u0636', '\u0631']), ('\ufd11',
- &['\u0637', '\u0649']), ('\ufd12', &['\u0637', '\u064a']), ('\ufd13', &['\u0639',
- '\u0649']), ('\ufd14', &['\u0639', '\u064a']), ('\ufd15', &['\u063a', '\u0649']), ('\ufd16',
- &['\u063a', '\u064a']), ('\ufd17', &['\u0633', '\u0649']), ('\ufd18', &['\u0633',
- '\u064a']), ('\ufd19', &['\u0634', '\u0649']), ('\ufd1a', &['\u0634', '\u064a']), ('\ufd1b',
- &['\u062d', '\u0649']), ('\ufd1c', &['\u062d', '\u064a']), ('\ufd1d', &['\u062c',
- '\u0649']), ('\ufd1e', &['\u062c', '\u064a']), ('\ufd1f', &['\u062e', '\u0649']), ('\ufd20',
- &['\u062e', '\u064a']), ('\ufd21', &['\u0635', '\u0649']), ('\ufd22', &['\u0635',
- '\u064a']), ('\ufd23', &['\u0636', '\u0649']), ('\ufd24', &['\u0636', '\u064a']), ('\ufd25',
- &['\u0634', '\u062c']), ('\ufd26', &['\u0634', '\u062d']), ('\ufd27', &['\u0634',
- '\u062e']), ('\ufd28', &['\u0634', '\u0645']), ('\ufd29', &['\u0634', '\u0631']), ('\ufd2a',
- &['\u0633', '\u0631']), ('\ufd2b', &['\u0635', '\u0631']), ('\ufd2c', &['\u0636',
- '\u0631']), ('\ufd2d', &['\u0634', '\u062c']), ('\ufd2e', &['\u0634', '\u062d']), ('\ufd2f',
- &['\u0634', '\u062e']), ('\ufd30', &['\u0634', '\u0645']), ('\ufd31', &['\u0633',
- '\u0647']), ('\ufd32', &['\u0634', '\u0647']), ('\ufd33', &['\u0637', '\u0645']), ('\ufd34',
- &['\u0633', '\u062c']), ('\ufd35', &['\u0633', '\u062d']), ('\ufd36', &['\u0633',
- '\u062e']), ('\ufd37', &['\u0634', '\u062c']), ('\ufd38', &['\u0634', '\u062d']), ('\ufd39',
- &['\u0634', '\u062e']), ('\ufd3a', &['\u0637', '\u0645']), ('\ufd3b', &['\u0638',
- '\u0645']), ('\ufd3c', &['\u0627', '\u064b']), ('\ufd3d', &['\u0627', '\u064b']), ('\ufd50',
- &['\u062a', '\u062c', '\u0645']), ('\ufd51', &['\u062a', '\u062d', '\u062c']), ('\ufd52',
- &['\u062a', '\u062d', '\u062c']), ('\ufd53', &['\u062a', '\u062d', '\u0645']), ('\ufd54',
- &['\u062a', '\u062e', '\u0645']), ('\ufd55', &['\u062a', '\u0645', '\u062c']), ('\ufd56',
- &['\u062a', '\u0645', '\u062d']), ('\ufd57', &['\u062a', '\u0645', '\u062e']), ('\ufd58',
- &['\u062c', '\u0645', '\u062d']), ('\ufd59', &['\u062c', '\u0645', '\u062d']), ('\ufd5a',
- &['\u062d', '\u0645', '\u064a']), ('\ufd5b', &['\u062d', '\u0645', '\u0649']), ('\ufd5c',
- &['\u0633', '\u062d', '\u062c']), ('\ufd5d', &['\u0633', '\u062c', '\u062d']), ('\ufd5e',
- &['\u0633', '\u062c', '\u0649']), ('\ufd5f', &['\u0633', '\u0645', '\u062d']), ('\ufd60',
- &['\u0633', '\u0645', '\u062d']), ('\ufd61', &['\u0633', '\u0645', '\u062c']), ('\ufd62',
- &['\u0633', '\u0645', '\u0645']), ('\ufd63', &['\u0633', '\u0645', '\u0645']), ('\ufd64',
- &['\u0635', '\u062d', '\u062d']), ('\ufd65', &['\u0635', '\u062d', '\u062d']), ('\ufd66',
- &['\u0635', '\u0645', '\u0645']), ('\ufd67', &['\u0634', '\u062d', '\u0645']), ('\ufd68',
- &['\u0634', '\u062d', '\u0645']), ('\ufd69', &['\u0634', '\u062c', '\u064a']), ('\ufd6a',
- &['\u0634', '\u0645', '\u062e']), ('\ufd6b', &['\u0634', '\u0645', '\u062e']), ('\ufd6c',
- &['\u0634', '\u0645', '\u0645']), ('\ufd6d', &['\u0634', '\u0645', '\u0645']), ('\ufd6e',
- &['\u0636', '\u062d', '\u0649']), ('\ufd6f', &['\u0636', '\u062e', '\u0645']), ('\ufd70',
- &['\u0636', '\u062e', '\u0645']), ('\ufd71', &['\u0637', '\u0645', '\u062d']), ('\ufd72',
- &['\u0637', '\u0645', '\u062d']), ('\ufd73', &['\u0637', '\u0645', '\u0645']), ('\ufd74',
- &['\u0637', '\u0645', '\u064a']), ('\ufd75', &['\u0639', '\u062c', '\u0645']), ('\ufd76',
- &['\u0639', '\u0645', '\u0645']), ('\ufd77', &['\u0639', '\u0645', '\u0645']), ('\ufd78',
- &['\u0639', '\u0645', '\u0649']), ('\ufd79', &['\u063a', '\u0645', '\u0645']), ('\ufd7a',
- &['\u063a', '\u0645', '\u064a']), ('\ufd7b', &['\u063a', '\u0645', '\u0649']), ('\ufd7c',
- &['\u0641', '\u062e', '\u0645']), ('\ufd7d', &['\u0641', '\u062e', '\u0645']), ('\ufd7e',
- &['\u0642', '\u0645', '\u062d']), ('\ufd7f', &['\u0642', '\u0645', '\u0645']), ('\ufd80',
- &['\u0644', '\u062d', '\u0645']), ('\ufd81', &['\u0644', '\u062d', '\u064a']), ('\ufd82',
- &['\u0644', '\u062d', '\u0649']), ('\ufd83', &['\u0644', '\u062c', '\u062c']), ('\ufd84',
- &['\u0644', '\u062c', '\u062c']), ('\ufd85', &['\u0644', '\u062e', '\u0645']), ('\ufd86',
- &['\u0644', '\u062e', '\u0645']), ('\ufd87', &['\u0644', '\u0645', '\u062d']), ('\ufd88',
- &['\u0644', '\u0645', '\u062d']), ('\ufd89', &['\u0645', '\u062d', '\u062c']), ('\ufd8a',
- &['\u0645', '\u062d', '\u0645']), ('\ufd8b', &['\u0645', '\u062d', '\u064a']), ('\ufd8c',
- &['\u0645', '\u062c', '\u062d']), ('\ufd8d', &['\u0645', '\u062c', '\u0645']), ('\ufd8e',
- &['\u0645', '\u062e', '\u062c']), ('\ufd8f', &['\u0645', '\u062e', '\u0645']), ('\ufd92',
- &['\u0645', '\u062c', '\u062e']), ('\ufd93', &['\u0647', '\u0645', '\u062c']), ('\ufd94',
- &['\u0647', '\u0645', '\u0645']), ('\ufd95', &['\u0646', '\u062d', '\u0645']), ('\ufd96',
- &['\u0646', '\u062d', '\u0649']), ('\ufd97', &['\u0646', '\u062c', '\u0645']), ('\ufd98',
- &['\u0646', '\u062c', '\u0645']), ('\ufd99', &['\u0646', '\u062c', '\u0649']), ('\ufd9a',
- &['\u0646', '\u0645', '\u064a']), ('\ufd9b', &['\u0646', '\u0645', '\u0649']), ('\ufd9c',
- &['\u064a', '\u0645', '\u0645']), ('\ufd9d', &['\u064a', '\u0645', '\u0645']), ('\ufd9e',
- &['\u0628', '\u062e', '\u064a']), ('\ufd9f', &['\u062a', '\u062c', '\u064a']), ('\ufda0',
- &['\u062a', '\u062c', '\u0649']), ('\ufda1', &['\u062a', '\u062e', '\u064a']), ('\ufda2',
- &['\u062a', '\u062e', '\u0649']), ('\ufda3', &['\u062a', '\u0645', '\u064a']), ('\ufda4',
- &['\u062a', '\u0645', '\u0649']), ('\ufda5', &['\u062c', '\u0645', '\u064a']), ('\ufda6',
- &['\u062c', '\u062d', '\u0649']), ('\ufda7', &['\u062c', '\u0645', '\u0649']), ('\ufda8',
- &['\u0633', '\u062e', '\u0649']), ('\ufda9', &['\u0635', '\u062d', '\u064a']), ('\ufdaa',
- &['\u0634', '\u062d', '\u064a']), ('\ufdab', &['\u0636', '\u062d', '\u064a']), ('\ufdac',
- &['\u0644', '\u062c', '\u064a']), ('\ufdad', &['\u0644', '\u0645', '\u064a']), ('\ufdae',
- &['\u064a', '\u062d', '\u064a']), ('\ufdaf', &['\u064a', '\u062c', '\u064a']), ('\ufdb0',
- &['\u064a', '\u0645', '\u064a']), ('\ufdb1', &['\u0645', '\u0645', '\u064a']), ('\ufdb2',
- &['\u0642', '\u0645', '\u064a']), ('\ufdb3', &['\u0646', '\u062d', '\u064a']), ('\ufdb4',
- &['\u0642', '\u0645', '\u062d']), ('\ufdb5', &['\u0644', '\u062d', '\u0645']), ('\ufdb6',
- &['\u0639', '\u0645', '\u064a']), ('\ufdb7', &['\u0643', '\u0645', '\u064a']), ('\ufdb8',
- &['\u0646', '\u062c', '\u062d']), ('\ufdb9', &['\u0645', '\u062e', '\u064a']), ('\ufdba',
- &['\u0644', '\u062c', '\u0645']), ('\ufdbb', &['\u0643', '\u0645', '\u0645']), ('\ufdbc',
- &['\u0644', '\u062c', '\u0645']), ('\ufdbd', &['\u0646', '\u062c', '\u062d']), ('\ufdbe',
- &['\u062c', '\u062d', '\u064a']), ('\ufdbf', &['\u062d', '\u062c', '\u064a']), ('\ufdc0',
- &['\u0645', '\u062c', '\u064a']), ('\ufdc1', &['\u0641', '\u0645', '\u064a']), ('\ufdc2',
- &['\u0628', '\u062d', '\u064a']), ('\ufdc3', &['\u0643', '\u0645', '\u0645']), ('\ufdc4',
- &['\u0639', '\u062c', '\u0645']), ('\ufdc5', &['\u0635', '\u0645', '\u0645']), ('\ufdc6',
- &['\u0633', '\u062e', '\u064a']), ('\ufdc7', &['\u0646', '\u062c', '\u064a']), ('\ufdf0',
- &['\u0635', '\u0644', '\u06d2']), ('\ufdf1', &['\u0642', '\u0644', '\u06d2']), ('\ufdf2',
- &['\u0627', '\u0644', '\u0644', '\u0647']), ('\ufdf3', &['\u0627', '\u0643', '\u0628',
- '\u0631']), ('\ufdf4', &['\u0645', '\u062d', '\u0645', '\u062f']), ('\ufdf5', &['\u0635',
- '\u0644', '\u0639', '\u0645']), ('\ufdf6', &['\u0631', '\u0633', '\u0648', '\u0644']),
- ('\ufdf7', &['\u0639', '\u0644', '\u064a', '\u0647']), ('\ufdf8', &['\u0648', '\u0633',
- '\u0644', '\u0645']), ('\ufdf9', &['\u0635', '\u0644', '\u0649']), ('\ufdfa', &['\u0635',
- '\u0644', '\u0649', '\x20', '\u0627', '\u0644', '\u0644', '\u0647', '\x20', '\u0639',
- '\u0644', '\u064a', '\u0647', '\x20', '\u0648', '\u0633', '\u0644', '\u0645']), ('\ufdfb',
- &['\u062c', '\u0644', '\x20', '\u062c', '\u0644', '\u0627', '\u0644', '\u0647']), ('\ufdfc',
- &['\u0631', '\u06cc', '\u0627', '\u0644']), ('\ufe10', &['\x2c']), ('\ufe11', &['\u3001']),
- ('\ufe12', &['\u3002']), ('\ufe13', &['\x3a']), ('\ufe14', &['\x3b']), ('\ufe15',
- &['\x21']), ('\ufe16', &['\x3f']), ('\ufe17', &['\u3016']), ('\ufe18', &['\u3017']),
- ('\ufe19', &['\u2026']), ('\ufe30', &['\u2025']), ('\ufe31', &['\u2014']), ('\ufe32',
- &['\u2013']), ('\ufe33', &['\x5f']), ('\ufe34', &['\x5f']), ('\ufe35', &['\x28']),
- ('\ufe36', &['\x29']), ('\ufe37', &['\x7b']), ('\ufe38', &['\x7d']), ('\ufe39',
- &['\u3014']), ('\ufe3a', &['\u3015']), ('\ufe3b', &['\u3010']), ('\ufe3c', &['\u3011']),
- ('\ufe3d', &['\u300a']), ('\ufe3e', &['\u300b']), ('\ufe3f', &['\u3008']), ('\ufe40',
- &['\u3009']), ('\ufe41', &['\u300c']), ('\ufe42', &['\u300d']), ('\ufe43', &['\u300e']),
- ('\ufe44', &['\u300f']), ('\ufe47', &['\x5b']), ('\ufe48', &['\x5d']), ('\ufe49',
- &['\u203e']), ('\ufe4a', &['\u203e']), ('\ufe4b', &['\u203e']), ('\ufe4c', &['\u203e']),
- ('\ufe4d', &['\x5f']), ('\ufe4e', &['\x5f']), ('\ufe4f', &['\x5f']), ('\ufe50', &['\x2c']),
- ('\ufe51', &['\u3001']), ('\ufe52', &['\x2e']), ('\ufe54', &['\x3b']), ('\ufe55',
- &['\x3a']), ('\ufe56', &['\x3f']), ('\ufe57', &['\x21']), ('\ufe58', &['\u2014']),
- ('\ufe59', &['\x28']), ('\ufe5a', &['\x29']), ('\ufe5b', &['\x7b']), ('\ufe5c', &['\x7d']),
- ('\ufe5d', &['\u3014']), ('\ufe5e', &['\u3015']), ('\ufe5f', &['\x23']), ('\ufe60',
- &['\x26']), ('\ufe61', &['\x2a']), ('\ufe62', &['\x2b']), ('\ufe63', &['\x2d']), ('\ufe64',
- &['\x3c']), ('\ufe65', &['\x3e']), ('\ufe66', &['\x3d']), ('\ufe68', &['\x5c']), ('\ufe69',
- &['\x24']), ('\ufe6a', &['\x25']), ('\ufe6b', &['\x40']), ('\ufe70', &['\x20', '\u064b']),
- ('\ufe71', &['\u0640', '\u064b']), ('\ufe72', &['\x20', '\u064c']), ('\ufe74', &['\x20',
- '\u064d']), ('\ufe76', &['\x20', '\u064e']), ('\ufe77', &['\u0640', '\u064e']), ('\ufe78',
- &['\x20', '\u064f']), ('\ufe79', &['\u0640', '\u064f']), ('\ufe7a', &['\x20', '\u0650']),
- ('\ufe7b', &['\u0640', '\u0650']), ('\ufe7c', &['\x20', '\u0651']), ('\ufe7d', &['\u0640',
- '\u0651']), ('\ufe7e', &['\x20', '\u0652']), ('\ufe7f', &['\u0640', '\u0652']), ('\ufe80',
- &['\u0621']), ('\ufe81', &['\u0622']), ('\ufe82', &['\u0622']), ('\ufe83', &['\u0623']),
- ('\ufe84', &['\u0623']), ('\ufe85', &['\u0624']), ('\ufe86', &['\u0624']), ('\ufe87',
- &['\u0625']), ('\ufe88', &['\u0625']), ('\ufe89', &['\u0626']), ('\ufe8a', &['\u0626']),
- ('\ufe8b', &['\u0626']), ('\ufe8c', &['\u0626']), ('\ufe8d', &['\u0627']), ('\ufe8e',
- &['\u0627']), ('\ufe8f', &['\u0628']), ('\ufe90', &['\u0628']), ('\ufe91', &['\u0628']),
- ('\ufe92', &['\u0628']), ('\ufe93', &['\u0629']), ('\ufe94', &['\u0629']), ('\ufe95',
- &['\u062a']), ('\ufe96', &['\u062a']), ('\ufe97', &['\u062a']), ('\ufe98', &['\u062a']),
- ('\ufe99', &['\u062b']), ('\ufe9a', &['\u062b']), ('\ufe9b', &['\u062b']), ('\ufe9c',
- &['\u062b']), ('\ufe9d', &['\u062c']), ('\ufe9e', &['\u062c']), ('\ufe9f', &['\u062c']),
- ('\ufea0', &['\u062c']), ('\ufea1', &['\u062d']), ('\ufea2', &['\u062d']), ('\ufea3',
- &['\u062d']), ('\ufea4', &['\u062d']), ('\ufea5', &['\u062e']), ('\ufea6', &['\u062e']),
- ('\ufea7', &['\u062e']), ('\ufea8', &['\u062e']), ('\ufea9', &['\u062f']), ('\ufeaa',
- &['\u062f']), ('\ufeab', &['\u0630']), ('\ufeac', &['\u0630']), ('\ufead', &['\u0631']),
- ('\ufeae', &['\u0631']), ('\ufeaf', &['\u0632']), ('\ufeb0', &['\u0632']), ('\ufeb1',
- &['\u0633']), ('\ufeb2', &['\u0633']), ('\ufeb3', &['\u0633']), ('\ufeb4', &['\u0633']),
- ('\ufeb5', &['\u0634']), ('\ufeb6', &['\u0634']), ('\ufeb7', &['\u0634']), ('\ufeb8',
- &['\u0634']), ('\ufeb9', &['\u0635']), ('\ufeba', &['\u0635']), ('\ufebb', &['\u0635']),
- ('\ufebc', &['\u0635']), ('\ufebd', &['\u0636']), ('\ufebe', &['\u0636']), ('\ufebf',
- &['\u0636']), ('\ufec0', &['\u0636']), ('\ufec1', &['\u0637']), ('\ufec2', &['\u0637']),
- ('\ufec3', &['\u0637']), ('\ufec4', &['\u0637']), ('\ufec5', &['\u0638']), ('\ufec6',
- &['\u0638']), ('\ufec7', &['\u0638']), ('\ufec8', &['\u0638']), ('\ufec9', &['\u0639']),
- ('\ufeca', &['\u0639']), ('\ufecb', &['\u0639']), ('\ufecc', &['\u0639']), ('\ufecd',
- &['\u063a']), ('\ufece', &['\u063a']), ('\ufecf', &['\u063a']), ('\ufed0', &['\u063a']),
- ('\ufed1', &['\u0641']), ('\ufed2', &['\u0641']), ('\ufed3', &['\u0641']), ('\ufed4',
- &['\u0641']), ('\ufed5', &['\u0642']), ('\ufed6', &['\u0642']), ('\ufed7', &['\u0642']),
- ('\ufed8', &['\u0642']), ('\ufed9', &['\u0643']), ('\ufeda', &['\u0643']), ('\ufedb',
- &['\u0643']), ('\ufedc', &['\u0643']), ('\ufedd', &['\u0644']), ('\ufede', &['\u0644']),
- ('\ufedf', &['\u0644']), ('\ufee0', &['\u0644']), ('\ufee1', &['\u0645']), ('\ufee2',
- &['\u0645']), ('\ufee3', &['\u0645']), ('\ufee4', &['\u0645']), ('\ufee5', &['\u0646']),
- ('\ufee6', &['\u0646']), ('\ufee7', &['\u0646']), ('\ufee8', &['\u0646']), ('\ufee9',
- &['\u0647']), ('\ufeea', &['\u0647']), ('\ufeeb', &['\u0647']), ('\ufeec', &['\u0647']),
- ('\ufeed', &['\u0648']), ('\ufeee', &['\u0648']), ('\ufeef', &['\u0649']), ('\ufef0',
- &['\u0649']), ('\ufef1', &['\u064a']), ('\ufef2', &['\u064a']), ('\ufef3', &['\u064a']),
- ('\ufef4', &['\u064a']), ('\ufef5', &['\u0644', '\u0622']), ('\ufef6', &['\u0644',
- '\u0622']), ('\ufef7', &['\u0644', '\u0623']), ('\ufef8', &['\u0644', '\u0623']), ('\ufef9',
- &['\u0644', '\u0625']), ('\ufefa', &['\u0644', '\u0625']), ('\ufefb', &['\u0644',
- '\u0627']), ('\ufefc', &['\u0644', '\u0627']), ('\uff01', &['\x21']), ('\uff02', &['\x22']),
- ('\uff03', &['\x23']), ('\uff04', &['\x24']), ('\uff05', &['\x25']), ('\uff06', &['\x26']),
- ('\uff07', &['\x27']), ('\uff08', &['\x28']), ('\uff09', &['\x29']), ('\uff0a', &['\x2a']),
- ('\uff0b', &['\x2b']), ('\uff0c', &['\x2c']), ('\uff0d', &['\x2d']), ('\uff0e', &['\x2e']),
- ('\uff0f', &['\x2f']), ('\uff10', &['\x30']), ('\uff11', &['\x31']), ('\uff12', &['\x32']),
- ('\uff13', &['\x33']), ('\uff14', &['\x34']), ('\uff15', &['\x35']), ('\uff16', &['\x36']),
- ('\uff17', &['\x37']), ('\uff18', &['\x38']), ('\uff19', &['\x39']), ('\uff1a', &['\x3a']),
- ('\uff1b', &['\x3b']), ('\uff1c', &['\x3c']), ('\uff1d', &['\x3d']), ('\uff1e', &['\x3e']),
- ('\uff1f', &['\x3f']), ('\uff20', &['\x40']), ('\uff21', &['\x41']), ('\uff22', &['\x42']),
- ('\uff23', &['\x43']), ('\uff24', &['\x44']), ('\uff25', &['\x45']), ('\uff26', &['\x46']),
- ('\uff27', &['\x47']), ('\uff28', &['\x48']), ('\uff29', &['\x49']), ('\uff2a', &['\x4a']),
- ('\uff2b', &['\x4b']), ('\uff2c', &['\x4c']), ('\uff2d', &['\x4d']), ('\uff2e', &['\x4e']),
- ('\uff2f', &['\x4f']), ('\uff30', &['\x50']), ('\uff31', &['\x51']), ('\uff32', &['\x52']),
- ('\uff33', &['\x53']), ('\uff34', &['\x54']), ('\uff35', &['\x55']), ('\uff36', &['\x56']),
- ('\uff37', &['\x57']), ('\uff38', &['\x58']), ('\uff39', &['\x59']), ('\uff3a', &['\x5a']),
- ('\uff3b', &['\x5b']), ('\uff3c', &['\x5c']), ('\uff3d', &['\x5d']), ('\uff3e', &['\x5e']),
- ('\uff3f', &['\x5f']), ('\uff40', &['\x60']), ('\uff41', &['\x61']), ('\uff42', &['\x62']),
- ('\uff43', &['\x63']), ('\uff44', &['\x64']), ('\uff45', &['\x65']), ('\uff46', &['\x66']),
- ('\uff47', &['\x67']), ('\uff48', &['\x68']), ('\uff49', &['\x69']), ('\uff4a', &['\x6a']),
- ('\uff4b', &['\x6b']), ('\uff4c', &['\x6c']), ('\uff4d', &['\x6d']), ('\uff4e', &['\x6e']),
- ('\uff4f', &['\x6f']), ('\uff50', &['\x70']), ('\uff51', &['\x71']), ('\uff52', &['\x72']),
- ('\uff53', &['\x73']), ('\uff54', &['\x74']), ('\uff55', &['\x75']), ('\uff56', &['\x76']),
- ('\uff57', &['\x77']), ('\uff58', &['\x78']), ('\uff59', &['\x79']), ('\uff5a', &['\x7a']),
- ('\uff5b', &['\x7b']), ('\uff5c', &['\x7c']), ('\uff5d', &['\x7d']), ('\uff5e', &['\x7e']),
- ('\uff5f', &['\u2985']), ('\uff60', &['\u2986']), ('\uff61', &['\u3002']), ('\uff62',
- &['\u300c']), ('\uff63', &['\u300d']), ('\uff64', &['\u3001']), ('\uff65', &['\u30fb']),
- ('\uff66', &['\u30f2']), ('\uff67', &['\u30a1']), ('\uff68', &['\u30a3']), ('\uff69',
- &['\u30a5']), ('\uff6a', &['\u30a7']), ('\uff6b', &['\u30a9']), ('\uff6c', &['\u30e3']),
- ('\uff6d', &['\u30e5']), ('\uff6e', &['\u30e7']), ('\uff6f', &['\u30c3']), ('\uff70',
- &['\u30fc']), ('\uff71', &['\u30a2']), ('\uff72', &['\u30a4']), ('\uff73', &['\u30a6']),
- ('\uff74', &['\u30a8']), ('\uff75', &['\u30aa']), ('\uff76', &['\u30ab']), ('\uff77',
- &['\u30ad']), ('\uff78', &['\u30af']), ('\uff79', &['\u30b1']), ('\uff7a', &['\u30b3']),
- ('\uff7b', &['\u30b5']), ('\uff7c', &['\u30b7']), ('\uff7d', &['\u30b9']), ('\uff7e',
- &['\u30bb']), ('\uff7f', &['\u30bd']), ('\uff80', &['\u30bf']), ('\uff81', &['\u30c1']),
- ('\uff82', &['\u30c4']), ('\uff83', &['\u30c6']), ('\uff84', &['\u30c8']), ('\uff85',
- &['\u30ca']), ('\uff86', &['\u30cb']), ('\uff87', &['\u30cc']), ('\uff88', &['\u30cd']),
- ('\uff89', &['\u30ce']), ('\uff8a', &['\u30cf']), ('\uff8b', &['\u30d2']), ('\uff8c',
- &['\u30d5']), ('\uff8d', &['\u30d8']), ('\uff8e', &['\u30db']), ('\uff8f', &['\u30de']),
- ('\uff90', &['\u30df']), ('\uff91', &['\u30e0']), ('\uff92', &['\u30e1']), ('\uff93',
- &['\u30e2']), ('\uff94', &['\u30e4']), ('\uff95', &['\u30e6']), ('\uff96', &['\u30e8']),
- ('\uff97', &['\u30e9']), ('\uff98', &['\u30ea']), ('\uff99', &['\u30eb']), ('\uff9a',
- &['\u30ec']), ('\uff9b', &['\u30ed']), ('\uff9c', &['\u30ef']), ('\uff9d', &['\u30f3']),
- ('\uff9e', &['\u3099']), ('\uff9f', &['\u309a']), ('\uffa0', &['\u3164']), ('\uffa1',
- &['\u3131']), ('\uffa2', &['\u3132']), ('\uffa3', &['\u3133']), ('\uffa4', &['\u3134']),
- ('\uffa5', &['\u3135']), ('\uffa6', &['\u3136']), ('\uffa7', &['\u3137']), ('\uffa8',
- &['\u3138']), ('\uffa9', &['\u3139']), ('\uffaa', &['\u313a']), ('\uffab', &['\u313b']),
- ('\uffac', &['\u313c']), ('\uffad', &['\u313d']), ('\uffae', &['\u313e']), ('\uffaf',
- &['\u313f']), ('\uffb0', &['\u3140']), ('\uffb1', &['\u3141']), ('\uffb2', &['\u3142']),
- ('\uffb3', &['\u3143']), ('\uffb4', &['\u3144']), ('\uffb5', &['\u3145']), ('\uffb6',
- &['\u3146']), ('\uffb7', &['\u3147']), ('\uffb8', &['\u3148']), ('\uffb9', &['\u3149']),
- ('\uffba', &['\u314a']), ('\uffbb', &['\u314b']), ('\uffbc', &['\u314c']), ('\uffbd',
- &['\u314d']), ('\uffbe', &['\u314e']), ('\uffc2', &['\u314f']), ('\uffc3', &['\u3150']),
- ('\uffc4', &['\u3151']), ('\uffc5', &['\u3152']), ('\uffc6', &['\u3153']), ('\uffc7',
- &['\u3154']), ('\uffca', &['\u3155']), ('\uffcb', &['\u3156']), ('\uffcc', &['\u3157']),
- ('\uffcd', &['\u3158']), ('\uffce', &['\u3159']), ('\uffcf', &['\u315a']), ('\uffd2',
- &['\u315b']), ('\uffd3', &['\u315c']), ('\uffd4', &['\u315d']), ('\uffd5', &['\u315e']),
- ('\uffd6', &['\u315f']), ('\uffd7', &['\u3160']), ('\uffda', &['\u3161']), ('\uffdb',
- &['\u3162']), ('\uffdc', &['\u3163']), ('\uffe0', &['\xa2']), ('\uffe1', &['\xa3']),
- ('\uffe2', &['\xac']), ('\uffe3', &['\xaf']), ('\uffe4', &['\xa6']), ('\uffe5', &['\xa5']),
- ('\uffe6', &['\u20a9']), ('\uffe8', &['\u2502']), ('\uffe9', &['\u2190']), ('\uffea',
- &['\u2191']), ('\uffeb', &['\u2192']), ('\uffec', &['\u2193']), ('\uffed', &['\u25a0']),
- ('\uffee', &['\u25cb']), ('\U0001d400', &['\x41']), ('\U0001d401', &['\x42']),
- ('\U0001d402', &['\x43']), ('\U0001d403', &['\x44']), ('\U0001d404', &['\x45']),
- ('\U0001d405', &['\x46']), ('\U0001d406', &['\x47']), ('\U0001d407', &['\x48']),
- ('\U0001d408', &['\x49']), ('\U0001d409', &['\x4a']), ('\U0001d40a', &['\x4b']),
- ('\U0001d40b', &['\x4c']), ('\U0001d40c', &['\x4d']), ('\U0001d40d', &['\x4e']),
- ('\U0001d40e', &['\x4f']), ('\U0001d40f', &['\x50']), ('\U0001d410', &['\x51']),
- ('\U0001d411', &['\x52']), ('\U0001d412', &['\x53']), ('\U0001d413', &['\x54']),
- ('\U0001d414', &['\x55']), ('\U0001d415', &['\x56']), ('\U0001d416', &['\x57']),
- ('\U0001d417', &['\x58']), ('\U0001d418', &['\x59']), ('\U0001d419', &['\x5a']),
- ('\U0001d41a', &['\x61']), ('\U0001d41b', &['\x62']), ('\U0001d41c', &['\x63']),
- ('\U0001d41d', &['\x64']), ('\U0001d41e', &['\x65']), ('\U0001d41f', &['\x66']),
- ('\U0001d420', &['\x67']), ('\U0001d421', &['\x68']), ('\U0001d422', &['\x69']),
- ('\U0001d423', &['\x6a']), ('\U0001d424', &['\x6b']), ('\U0001d425', &['\x6c']),
- ('\U0001d426', &['\x6d']), ('\U0001d427', &['\x6e']), ('\U0001d428', &['\x6f']),
- ('\U0001d429', &['\x70']), ('\U0001d42a', &['\x71']), ('\U0001d42b', &['\x72']),
- ('\U0001d42c', &['\x73']), ('\U0001d42d', &['\x74']), ('\U0001d42e', &['\x75']),
- ('\U0001d42f', &['\x76']), ('\U0001d430', &['\x77']), ('\U0001d431', &['\x78']),
- ('\U0001d432', &['\x79']), ('\U0001d433', &['\x7a']), ('\U0001d434', &['\x41']),
- ('\U0001d435', &['\x42']), ('\U0001d436', &['\x43']), ('\U0001d437', &['\x44']),
- ('\U0001d438', &['\x45']), ('\U0001d439', &['\x46']), ('\U0001d43a', &['\x47']),
- ('\U0001d43b', &['\x48']), ('\U0001d43c', &['\x49']), ('\U0001d43d', &['\x4a']),
- ('\U0001d43e', &['\x4b']), ('\U0001d43f', &['\x4c']), ('\U0001d440', &['\x4d']),
- ('\U0001d441', &['\x4e']), ('\U0001d442', &['\x4f']), ('\U0001d443', &['\x50']),
- ('\U0001d444', &['\x51']), ('\U0001d445', &['\x52']), ('\U0001d446', &['\x53']),
- ('\U0001d447', &['\x54']), ('\U0001d448', &['\x55']), ('\U0001d449', &['\x56']),
- ('\U0001d44a', &['\x57']), ('\U0001d44b', &['\x58']), ('\U0001d44c', &['\x59']),
- ('\U0001d44d', &['\x5a']), ('\U0001d44e', &['\x61']), ('\U0001d44f', &['\x62']),
- ('\U0001d450', &['\x63']), ('\U0001d451', &['\x64']), ('\U0001d452', &['\x65']),
- ('\U0001d453', &['\x66']), ('\U0001d454', &['\x67']), ('\U0001d456', &['\x69']),
- ('\U0001d457', &['\x6a']), ('\U0001d458', &['\x6b']), ('\U0001d459', &['\x6c']),
- ('\U0001d45a', &['\x6d']), ('\U0001d45b', &['\x6e']), ('\U0001d45c', &['\x6f']),
- ('\U0001d45d', &['\x70']), ('\U0001d45e', &['\x71']), ('\U0001d45f', &['\x72']),
- ('\U0001d460', &['\x73']), ('\U0001d461', &['\x74']), ('\U0001d462', &['\x75']),
- ('\U0001d463', &['\x76']), ('\U0001d464', &['\x77']), ('\U0001d465', &['\x78']),
- ('\U0001d466', &['\x79']), ('\U0001d467', &['\x7a']), ('\U0001d468', &['\x41']),
- ('\U0001d469', &['\x42']), ('\U0001d46a', &['\x43']), ('\U0001d46b', &['\x44']),
- ('\U0001d46c', &['\x45']), ('\U0001d46d', &['\x46']), ('\U0001d46e', &['\x47']),
- ('\U0001d46f', &['\x48']), ('\U0001d470', &['\x49']), ('\U0001d471', &['\x4a']),
- ('\U0001d472', &['\x4b']), ('\U0001d473', &['\x4c']), ('\U0001d474', &['\x4d']),
- ('\U0001d475', &['\x4e']), ('\U0001d476', &['\x4f']), ('\U0001d477', &['\x50']),
- ('\U0001d478', &['\x51']), ('\U0001d479', &['\x52']), ('\U0001d47a', &['\x53']),
- ('\U0001d47b', &['\x54']), ('\U0001d47c', &['\x55']), ('\U0001d47d', &['\x56']),
- ('\U0001d47e', &['\x57']), ('\U0001d47f', &['\x58']), ('\U0001d480', &['\x59']),
- ('\U0001d481', &['\x5a']), ('\U0001d482', &['\x61']), ('\U0001d483', &['\x62']),
- ('\U0001d484', &['\x63']), ('\U0001d485', &['\x64']), ('\U0001d486', &['\x65']),
- ('\U0001d487', &['\x66']), ('\U0001d488', &['\x67']), ('\U0001d489', &['\x68']),
- ('\U0001d48a', &['\x69']), ('\U0001d48b', &['\x6a']), ('\U0001d48c', &['\x6b']),
- ('\U0001d48d', &['\x6c']), ('\U0001d48e', &['\x6d']), ('\U0001d48f', &['\x6e']),
- ('\U0001d490', &['\x6f']), ('\U0001d491', &['\x70']), ('\U0001d492', &['\x71']),
- ('\U0001d493', &['\x72']), ('\U0001d494', &['\x73']), ('\U0001d495', &['\x74']),
- ('\U0001d496', &['\x75']), ('\U0001d497', &['\x76']), ('\U0001d498', &['\x77']),
- ('\U0001d499', &['\x78']), ('\U0001d49a', &['\x79']), ('\U0001d49b', &['\x7a']),
- ('\U0001d49c', &['\x41']), ('\U0001d49e', &['\x43']), ('\U0001d49f', &['\x44']),
- ('\U0001d4a2', &['\x47']), ('\U0001d4a5', &['\x4a']), ('\U0001d4a6', &['\x4b']),
- ('\U0001d4a9', &['\x4e']), ('\U0001d4aa', &['\x4f']), ('\U0001d4ab', &['\x50']),
- ('\U0001d4ac', &['\x51']), ('\U0001d4ae', &['\x53']), ('\U0001d4af', &['\x54']),
- ('\U0001d4b0', &['\x55']), ('\U0001d4b1', &['\x56']), ('\U0001d4b2', &['\x57']),
- ('\U0001d4b3', &['\x58']), ('\U0001d4b4', &['\x59']), ('\U0001d4b5', &['\x5a']),
- ('\U0001d4b6', &['\x61']), ('\U0001d4b7', &['\x62']), ('\U0001d4b8', &['\x63']),
- ('\U0001d4b9', &['\x64']), ('\U0001d4bb', &['\x66']), ('\U0001d4bd', &['\x68']),
- ('\U0001d4be', &['\x69']), ('\U0001d4bf', &['\x6a']), ('\U0001d4c0', &['\x6b']),
- ('\U0001d4c1', &['\x6c']), ('\U0001d4c2', &['\x6d']), ('\U0001d4c3', &['\x6e']),
- ('\U0001d4c5', &['\x70']), ('\U0001d4c6', &['\x71']), ('\U0001d4c7', &['\x72']),
- ('\U0001d4c8', &['\x73']), ('\U0001d4c9', &['\x74']), ('\U0001d4ca', &['\x75']),
- ('\U0001d4cb', &['\x76']), ('\U0001d4cc', &['\x77']), ('\U0001d4cd', &['\x78']),
- ('\U0001d4ce', &['\x79']), ('\U0001d4cf', &['\x7a']), ('\U0001d4d0', &['\x41']),
- ('\U0001d4d1', &['\x42']), ('\U0001d4d2', &['\x43']), ('\U0001d4d3', &['\x44']),
- ('\U0001d4d4', &['\x45']), ('\U0001d4d5', &['\x46']), ('\U0001d4d6', &['\x47']),
- ('\U0001d4d7', &['\x48']), ('\U0001d4d8', &['\x49']), ('\U0001d4d9', &['\x4a']),
- ('\U0001d4da', &['\x4b']), ('\U0001d4db', &['\x4c']), ('\U0001d4dc', &['\x4d']),
- ('\U0001d4dd', &['\x4e']), ('\U0001d4de', &['\x4f']), ('\U0001d4df', &['\x50']),
- ('\U0001d4e0', &['\x51']), ('\U0001d4e1', &['\x52']), ('\U0001d4e2', &['\x53']),
- ('\U0001d4e3', &['\x54']), ('\U0001d4e4', &['\x55']), ('\U0001d4e5', &['\x56']),
- ('\U0001d4e6', &['\x57']), ('\U0001d4e7', &['\x58']), ('\U0001d4e8', &['\x59']),
- ('\U0001d4e9', &['\x5a']), ('\U0001d4ea', &['\x61']), ('\U0001d4eb', &['\x62']),
- ('\U0001d4ec', &['\x63']), ('\U0001d4ed', &['\x64']), ('\U0001d4ee', &['\x65']),
- ('\U0001d4ef', &['\x66']), ('\U0001d4f0', &['\x67']), ('\U0001d4f1', &['\x68']),
- ('\U0001d4f2', &['\x69']), ('\U0001d4f3', &['\x6a']), ('\U0001d4f4', &['\x6b']),
- ('\U0001d4f5', &['\x6c']), ('\U0001d4f6', &['\x6d']), ('\U0001d4f7', &['\x6e']),
- ('\U0001d4f8', &['\x6f']), ('\U0001d4f9', &['\x70']), ('\U0001d4fa', &['\x71']),
- ('\U0001d4fb', &['\x72']), ('\U0001d4fc', &['\x73']), ('\U0001d4fd', &['\x74']),
- ('\U0001d4fe', &['\x75']), ('\U0001d4ff', &['\x76']), ('\U0001d500', &['\x77']),
- ('\U0001d501', &['\x78']), ('\U0001d502', &['\x79']), ('\U0001d503', &['\x7a']),
- ('\U0001d504', &['\x41']), ('\U0001d505', &['\x42']), ('\U0001d507', &['\x44']),
- ('\U0001d508', &['\x45']), ('\U0001d509', &['\x46']), ('\U0001d50a', &['\x47']),
- ('\U0001d50d', &['\x4a']), ('\U0001d50e', &['\x4b']), ('\U0001d50f', &['\x4c']),
- ('\U0001d510', &['\x4d']), ('\U0001d511', &['\x4e']), ('\U0001d512', &['\x4f']),
- ('\U0001d513', &['\x50']), ('\U0001d514', &['\x51']), ('\U0001d516', &['\x53']),
- ('\U0001d517', &['\x54']), ('\U0001d518', &['\x55']), ('\U0001d519', &['\x56']),
- ('\U0001d51a', &['\x57']), ('\U0001d51b', &['\x58']), ('\U0001d51c', &['\x59']),
- ('\U0001d51e', &['\x61']), ('\U0001d51f', &['\x62']), ('\U0001d520', &['\x63']),
- ('\U0001d521', &['\x64']), ('\U0001d522', &['\x65']), ('\U0001d523', &['\x66']),
- ('\U0001d524', &['\x67']), ('\U0001d525', &['\x68']), ('\U0001d526', &['\x69']),
- ('\U0001d527', &['\x6a']), ('\U0001d528', &['\x6b']), ('\U0001d529', &['\x6c']),
- ('\U0001d52a', &['\x6d']), ('\U0001d52b', &['\x6e']), ('\U0001d52c', &['\x6f']),
- ('\U0001d52d', &['\x70']), ('\U0001d52e', &['\x71']), ('\U0001d52f', &['\x72']),
- ('\U0001d530', &['\x73']), ('\U0001d531', &['\x74']), ('\U0001d532', &['\x75']),
- ('\U0001d533', &['\x76']), ('\U0001d534', &['\x77']), ('\U0001d535', &['\x78']),
- ('\U0001d536', &['\x79']), ('\U0001d537', &['\x7a']), ('\U0001d538', &['\x41']),
- ('\U0001d539', &['\x42']), ('\U0001d53b', &['\x44']), ('\U0001d53c', &['\x45']),
- ('\U0001d53d', &['\x46']), ('\U0001d53e', &['\x47']), ('\U0001d540', &['\x49']),
- ('\U0001d541', &['\x4a']), ('\U0001d542', &['\x4b']), ('\U0001d543', &['\x4c']),
- ('\U0001d544', &['\x4d']), ('\U0001d546', &['\x4f']), ('\U0001d54a', &['\x53']),
- ('\U0001d54b', &['\x54']), ('\U0001d54c', &['\x55']), ('\U0001d54d', &['\x56']),
- ('\U0001d54e', &['\x57']), ('\U0001d54f', &['\x58']), ('\U0001d550', &['\x59']),
- ('\U0001d552', &['\x61']), ('\U0001d553', &['\x62']), ('\U0001d554', &['\x63']),
- ('\U0001d555', &['\x64']), ('\U0001d556', &['\x65']), ('\U0001d557', &['\x66']),
- ('\U0001d558', &['\x67']), ('\U0001d559', &['\x68']), ('\U0001d55a', &['\x69']),
- ('\U0001d55b', &['\x6a']), ('\U0001d55c', &['\x6b']), ('\U0001d55d', &['\x6c']),
- ('\U0001d55e', &['\x6d']), ('\U0001d55f', &['\x6e']), ('\U0001d560', &['\x6f']),
- ('\U0001d561', &['\x70']), ('\U0001d562', &['\x71']), ('\U0001d563', &['\x72']),
- ('\U0001d564', &['\x73']), ('\U0001d565', &['\x74']), ('\U0001d566', &['\x75']),
- ('\U0001d567', &['\x76']), ('\U0001d568', &['\x77']), ('\U0001d569', &['\x78']),
- ('\U0001d56a', &['\x79']), ('\U0001d56b', &['\x7a']), ('\U0001d56c', &['\x41']),
- ('\U0001d56d', &['\x42']), ('\U0001d56e', &['\x43']), ('\U0001d56f', &['\x44']),
- ('\U0001d570', &['\x45']), ('\U0001d571', &['\x46']), ('\U0001d572', &['\x47']),
- ('\U0001d573', &['\x48']), ('\U0001d574', &['\x49']), ('\U0001d575', &['\x4a']),
- ('\U0001d576', &['\x4b']), ('\U0001d577', &['\x4c']), ('\U0001d578', &['\x4d']),
- ('\U0001d579', &['\x4e']), ('\U0001d57a', &['\x4f']), ('\U0001d57b', &['\x50']),
- ('\U0001d57c', &['\x51']), ('\U0001d57d', &['\x52']), ('\U0001d57e', &['\x53']),
- ('\U0001d57f', &['\x54']), ('\U0001d580', &['\x55']), ('\U0001d581', &['\x56']),
- ('\U0001d582', &['\x57']), ('\U0001d583', &['\x58']), ('\U0001d584', &['\x59']),
- ('\U0001d585', &['\x5a']), ('\U0001d586', &['\x61']), ('\U0001d587', &['\x62']),
- ('\U0001d588', &['\x63']), ('\U0001d589', &['\x64']), ('\U0001d58a', &['\x65']),
- ('\U0001d58b', &['\x66']), ('\U0001d58c', &['\x67']), ('\U0001d58d', &['\x68']),
- ('\U0001d58e', &['\x69']), ('\U0001d58f', &['\x6a']), ('\U0001d590', &['\x6b']),
- ('\U0001d591', &['\x6c']), ('\U0001d592', &['\x6d']), ('\U0001d593', &['\x6e']),
- ('\U0001d594', &['\x6f']), ('\U0001d595', &['\x70']), ('\U0001d596', &['\x71']),
- ('\U0001d597', &['\x72']), ('\U0001d598', &['\x73']), ('\U0001d599', &['\x74']),
- ('\U0001d59a', &['\x75']), ('\U0001d59b', &['\x76']), ('\U0001d59c', &['\x77']),
- ('\U0001d59d', &['\x78']), ('\U0001d59e', &['\x79']), ('\U0001d59f', &['\x7a']),
- ('\U0001d5a0', &['\x41']), ('\U0001d5a1', &['\x42']), ('\U0001d5a2', &['\x43']),
- ('\U0001d5a3', &['\x44']), ('\U0001d5a4', &['\x45']), ('\U0001d5a5', &['\x46']),
- ('\U0001d5a6', &['\x47']), ('\U0001d5a7', &['\x48']), ('\U0001d5a8', &['\x49']),
- ('\U0001d5a9', &['\x4a']), ('\U0001d5aa', &['\x4b']), ('\U0001d5ab', &['\x4c']),
- ('\U0001d5ac', &['\x4d']), ('\U0001d5ad', &['\x4e']), ('\U0001d5ae', &['\x4f']),
- ('\U0001d5af', &['\x50']), ('\U0001d5b0', &['\x51']), ('\U0001d5b1', &['\x52']),
- ('\U0001d5b2', &['\x53']), ('\U0001d5b3', &['\x54']), ('\U0001d5b4', &['\x55']),
- ('\U0001d5b5', &['\x56']), ('\U0001d5b6', &['\x57']), ('\U0001d5b7', &['\x58']),
- ('\U0001d5b8', &['\x59']), ('\U0001d5b9', &['\x5a']), ('\U0001d5ba', &['\x61']),
- ('\U0001d5bb', &['\x62']), ('\U0001d5bc', &['\x63']), ('\U0001d5bd', &['\x64']),
- ('\U0001d5be', &['\x65']), ('\U0001d5bf', &['\x66']), ('\U0001d5c0', &['\x67']),
- ('\U0001d5c1', &['\x68']), ('\U0001d5c2', &['\x69']), ('\U0001d5c3', &['\x6a']),
- ('\U0001d5c4', &['\x6b']), ('\U0001d5c5', &['\x6c']), ('\U0001d5c6', &['\x6d']),
- ('\U0001d5c7', &['\x6e']), ('\U0001d5c8', &['\x6f']), ('\U0001d5c9', &['\x70']),
- ('\U0001d5ca', &['\x71']), ('\U0001d5cb', &['\x72']), ('\U0001d5cc', &['\x73']),
- ('\U0001d5cd', &['\x74']), ('\U0001d5ce', &['\x75']), ('\U0001d5cf', &['\x76']),
- ('\U0001d5d0', &['\x77']), ('\U0001d5d1', &['\x78']), ('\U0001d5d2', &['\x79']),
- ('\U0001d5d3', &['\x7a']), ('\U0001d5d4', &['\x41']), ('\U0001d5d5', &['\x42']),
- ('\U0001d5d6', &['\x43']), ('\U0001d5d7', &['\x44']), ('\U0001d5d8', &['\x45']),
- ('\U0001d5d9', &['\x46']), ('\U0001d5da', &['\x47']), ('\U0001d5db', &['\x48']),
- ('\U0001d5dc', &['\x49']), ('\U0001d5dd', &['\x4a']), ('\U0001d5de', &['\x4b']),
- ('\U0001d5df', &['\x4c']), ('\U0001d5e0', &['\x4d']), ('\U0001d5e1', &['\x4e']),
- ('\U0001d5e2', &['\x4f']), ('\U0001d5e3', &['\x50']), ('\U0001d5e4', &['\x51']),
- ('\U0001d5e5', &['\x52']), ('\U0001d5e6', &['\x53']), ('\U0001d5e7', &['\x54']),
- ('\U0001d5e8', &['\x55']), ('\U0001d5e9', &['\x56']), ('\U0001d5ea', &['\x57']),
- ('\U0001d5eb', &['\x58']), ('\U0001d5ec', &['\x59']), ('\U0001d5ed', &['\x5a']),
- ('\U0001d5ee', &['\x61']), ('\U0001d5ef', &['\x62']), ('\U0001d5f0', &['\x63']),
- ('\U0001d5f1', &['\x64']), ('\U0001d5f2', &['\x65']), ('\U0001d5f3', &['\x66']),
- ('\U0001d5f4', &['\x67']), ('\U0001d5f5', &['\x68']), ('\U0001d5f6', &['\x69']),
- ('\U0001d5f7', &['\x6a']), ('\U0001d5f8', &['\x6b']), ('\U0001d5f9', &['\x6c']),
- ('\U0001d5fa', &['\x6d']), ('\U0001d5fb', &['\x6e']), ('\U0001d5fc', &['\x6f']),
- ('\U0001d5fd', &['\x70']), ('\U0001d5fe', &['\x71']), ('\U0001d5ff', &['\x72']),
- ('\U0001d600', &['\x73']), ('\U0001d601', &['\x74']), ('\U0001d602', &['\x75']),
- ('\U0001d603', &['\x76']), ('\U0001d604', &['\x77']), ('\U0001d605', &['\x78']),
- ('\U0001d606', &['\x79']), ('\U0001d607', &['\x7a']), ('\U0001d608', &['\x41']),
- ('\U0001d609', &['\x42']), ('\U0001d60a', &['\x43']), ('\U0001d60b', &['\x44']),
- ('\U0001d60c', &['\x45']), ('\U0001d60d', &['\x46']), ('\U0001d60e', &['\x47']),
- ('\U0001d60f', &['\x48']), ('\U0001d610', &['\x49']), ('\U0001d611', &['\x4a']),
- ('\U0001d612', &['\x4b']), ('\U0001d613', &['\x4c']), ('\U0001d614', &['\x4d']),
- ('\U0001d615', &['\x4e']), ('\U0001d616', &['\x4f']), ('\U0001d617', &['\x50']),
- ('\U0001d618', &['\x51']), ('\U0001d619', &['\x52']), ('\U0001d61a', &['\x53']),
- ('\U0001d61b', &['\x54']), ('\U0001d61c', &['\x55']), ('\U0001d61d', &['\x56']),
- ('\U0001d61e', &['\x57']), ('\U0001d61f', &['\x58']), ('\U0001d620', &['\x59']),
- ('\U0001d621', &['\x5a']), ('\U0001d622', &['\x61']), ('\U0001d623', &['\x62']),
- ('\U0001d624', &['\x63']), ('\U0001d625', &['\x64']), ('\U0001d626', &['\x65']),
- ('\U0001d627', &['\x66']), ('\U0001d628', &['\x67']), ('\U0001d629', &['\x68']),
- ('\U0001d62a', &['\x69']), ('\U0001d62b', &['\x6a']), ('\U0001d62c', &['\x6b']),
- ('\U0001d62d', &['\x6c']), ('\U0001d62e', &['\x6d']), ('\U0001d62f', &['\x6e']),
- ('\U0001d630', &['\x6f']), ('\U0001d631', &['\x70']), ('\U0001d632', &['\x71']),
- ('\U0001d633', &['\x72']), ('\U0001d634', &['\x73']), ('\U0001d635', &['\x74']),
- ('\U0001d636', &['\x75']), ('\U0001d637', &['\x76']), ('\U0001d638', &['\x77']),
- ('\U0001d639', &['\x78']), ('\U0001d63a', &['\x79']), ('\U0001d63b', &['\x7a']),
- ('\U0001d63c', &['\x41']), ('\U0001d63d', &['\x42']), ('\U0001d63e', &['\x43']),
- ('\U0001d63f', &['\x44']), ('\U0001d640', &['\x45']), ('\U0001d641', &['\x46']),
- ('\U0001d642', &['\x47']), ('\U0001d643', &['\x48']), ('\U0001d644', &['\x49']),
- ('\U0001d645', &['\x4a']), ('\U0001d646', &['\x4b']), ('\U0001d647', &['\x4c']),
- ('\U0001d648', &['\x4d']), ('\U0001d649', &['\x4e']), ('\U0001d64a', &['\x4f']),
- ('\U0001d64b', &['\x50']), ('\U0001d64c', &['\x51']), ('\U0001d64d', &['\x52']),
- ('\U0001d64e', &['\x53']), ('\U0001d64f', &['\x54']), ('\U0001d650', &['\x55']),
- ('\U0001d651', &['\x56']), ('\U0001d652', &['\x57']), ('\U0001d653', &['\x58']),
- ('\U0001d654', &['\x59']), ('\U0001d655', &['\x5a']), ('\U0001d656', &['\x61']),
- ('\U0001d657', &['\x62']), ('\U0001d658', &['\x63']), ('\U0001d659', &['\x64']),
- ('\U0001d65a', &['\x65']), ('\U0001d65b', &['\x66']), ('\U0001d65c', &['\x67']),
- ('\U0001d65d', &['\x68']), ('\U0001d65e', &['\x69']), ('\U0001d65f', &['\x6a']),
- ('\U0001d660', &['\x6b']), ('\U0001d661', &['\x6c']), ('\U0001d662', &['\x6d']),
- ('\U0001d663', &['\x6e']), ('\U0001d664', &['\x6f']), ('\U0001d665', &['\x70']),
- ('\U0001d666', &['\x71']), ('\U0001d667', &['\x72']), ('\U0001d668', &['\x73']),
- ('\U0001d669', &['\x74']), ('\U0001d66a', &['\x75']), ('\U0001d66b', &['\x76']),
- ('\U0001d66c', &['\x77']), ('\U0001d66d', &['\x78']), ('\U0001d66e', &['\x79']),
- ('\U0001d66f', &['\x7a']), ('\U0001d670', &['\x41']), ('\U0001d671', &['\x42']),
- ('\U0001d672', &['\x43']), ('\U0001d673', &['\x44']), ('\U0001d674', &['\x45']),
- ('\U0001d675', &['\x46']), ('\U0001d676', &['\x47']), ('\U0001d677', &['\x48']),
- ('\U0001d678', &['\x49']), ('\U0001d679', &['\x4a']), ('\U0001d67a', &['\x4b']),
- ('\U0001d67b', &['\x4c']), ('\U0001d67c', &['\x4d']), ('\U0001d67d', &['\x4e']),
- ('\U0001d67e', &['\x4f']), ('\U0001d67f', &['\x50']), ('\U0001d680', &['\x51']),
- ('\U0001d681', &['\x52']), ('\U0001d682', &['\x53']), ('\U0001d683', &['\x54']),
- ('\U0001d684', &['\x55']), ('\U0001d685', &['\x56']), ('\U0001d686', &['\x57']),
- ('\U0001d687', &['\x58']), ('\U0001d688', &['\x59']), ('\U0001d689', &['\x5a']),
- ('\U0001d68a', &['\x61']), ('\U0001d68b', &['\x62']), ('\U0001d68c', &['\x63']),
- ('\U0001d68d', &['\x64']), ('\U0001d68e', &['\x65']), ('\U0001d68f', &['\x66']),
- ('\U0001d690', &['\x67']), ('\U0001d691', &['\x68']), ('\U0001d692', &['\x69']),
- ('\U0001d693', &['\x6a']), ('\U0001d694', &['\x6b']), ('\U0001d695', &['\x6c']),
- ('\U0001d696', &['\x6d']), ('\U0001d697', &['\x6e']), ('\U0001d698', &['\x6f']),
- ('\U0001d699', &['\x70']), ('\U0001d69a', &['\x71']), ('\U0001d69b', &['\x72']),
- ('\U0001d69c', &['\x73']), ('\U0001d69d', &['\x74']), ('\U0001d69e', &['\x75']),
- ('\U0001d69f', &['\x76']), ('\U0001d6a0', &['\x77']), ('\U0001d6a1', &['\x78']),
- ('\U0001d6a2', &['\x79']), ('\U0001d6a3', &['\x7a']), ('\U0001d6a4', &['\u0131']),
- ('\U0001d6a5', &['\u0237']), ('\U0001d6a8', &['\u0391']), ('\U0001d6a9', &['\u0392']),
- ('\U0001d6aa', &['\u0393']), ('\U0001d6ab', &['\u0394']), ('\U0001d6ac', &['\u0395']),
- ('\U0001d6ad', &['\u0396']), ('\U0001d6ae', &['\u0397']), ('\U0001d6af', &['\u0398']),
- ('\U0001d6b0', &['\u0399']), ('\U0001d6b1', &['\u039a']), ('\U0001d6b2', &['\u039b']),
- ('\U0001d6b3', &['\u039c']), ('\U0001d6b4', &['\u039d']), ('\U0001d6b5', &['\u039e']),
- ('\U0001d6b6', &['\u039f']), ('\U0001d6b7', &['\u03a0']), ('\U0001d6b8', &['\u03a1']),
- ('\U0001d6b9', &['\u03f4']), ('\U0001d6ba', &['\u03a3']), ('\U0001d6bb', &['\u03a4']),
- ('\U0001d6bc', &['\u03a5']), ('\U0001d6bd', &['\u03a6']), ('\U0001d6be', &['\u03a7']),
- ('\U0001d6bf', &['\u03a8']), ('\U0001d6c0', &['\u03a9']), ('\U0001d6c1', &['\u2207']),
- ('\U0001d6c2', &['\u03b1']), ('\U0001d6c3', &['\u03b2']), ('\U0001d6c4', &['\u03b3']),
- ('\U0001d6c5', &['\u03b4']), ('\U0001d6c6', &['\u03b5']), ('\U0001d6c7', &['\u03b6']),
- ('\U0001d6c8', &['\u03b7']), ('\U0001d6c9', &['\u03b8']), ('\U0001d6ca', &['\u03b9']),
- ('\U0001d6cb', &['\u03ba']), ('\U0001d6cc', &['\u03bb']), ('\U0001d6cd', &['\u03bc']),
- ('\U0001d6ce', &['\u03bd']), ('\U0001d6cf', &['\u03be']), ('\U0001d6d0', &['\u03bf']),
- ('\U0001d6d1', &['\u03c0']), ('\U0001d6d2', &['\u03c1']), ('\U0001d6d3', &['\u03c2']),
- ('\U0001d6d4', &['\u03c3']), ('\U0001d6d5', &['\u03c4']), ('\U0001d6d6', &['\u03c5']),
- ('\U0001d6d7', &['\u03c6']), ('\U0001d6d8', &['\u03c7']), ('\U0001d6d9', &['\u03c8']),
- ('\U0001d6da', &['\u03c9']), ('\U0001d6db', &['\u2202']), ('\U0001d6dc', &['\u03f5']),
- ('\U0001d6dd', &['\u03d1']), ('\U0001d6de', &['\u03f0']), ('\U0001d6df', &['\u03d5']),
- ('\U0001d6e0', &['\u03f1']), ('\U0001d6e1', &['\u03d6']), ('\U0001d6e2', &['\u0391']),
- ('\U0001d6e3', &['\u0392']), ('\U0001d6e4', &['\u0393']), ('\U0001d6e5', &['\u0394']),
- ('\U0001d6e6', &['\u0395']), ('\U0001d6e7', &['\u0396']), ('\U0001d6e8', &['\u0397']),
- ('\U0001d6e9', &['\u0398']), ('\U0001d6ea', &['\u0399']), ('\U0001d6eb', &['\u039a']),
- ('\U0001d6ec', &['\u039b']), ('\U0001d6ed', &['\u039c']), ('\U0001d6ee', &['\u039d']),
- ('\U0001d6ef', &['\u039e']), ('\U0001d6f0', &['\u039f']), ('\U0001d6f1', &['\u03a0']),
- ('\U0001d6f2', &['\u03a1']), ('\U0001d6f3', &['\u03f4']), ('\U0001d6f4', &['\u03a3']),
- ('\U0001d6f5', &['\u03a4']), ('\U0001d6f6', &['\u03a5']), ('\U0001d6f7', &['\u03a6']),
- ('\U0001d6f8', &['\u03a7']), ('\U0001d6f9', &['\u03a8']), ('\U0001d6fa', &['\u03a9']),
- ('\U0001d6fb', &['\u2207']), ('\U0001d6fc', &['\u03b1']), ('\U0001d6fd', &['\u03b2']),
- ('\U0001d6fe', &['\u03b3']), ('\U0001d6ff', &['\u03b4']), ('\U0001d700', &['\u03b5']),
- ('\U0001d701', &['\u03b6']), ('\U0001d702', &['\u03b7']), ('\U0001d703', &['\u03b8']),
- ('\U0001d704', &['\u03b9']), ('\U0001d705', &['\u03ba']), ('\U0001d706', &['\u03bb']),
- ('\U0001d707', &['\u03bc']), ('\U0001d708', &['\u03bd']), ('\U0001d709', &['\u03be']),
- ('\U0001d70a', &['\u03bf']), ('\U0001d70b', &['\u03c0']), ('\U0001d70c', &['\u03c1']),
- ('\U0001d70d', &['\u03c2']), ('\U0001d70e', &['\u03c3']), ('\U0001d70f', &['\u03c4']),
- ('\U0001d710', &['\u03c5']), ('\U0001d711', &['\u03c6']), ('\U0001d712', &['\u03c7']),
- ('\U0001d713', &['\u03c8']), ('\U0001d714', &['\u03c9']), ('\U0001d715', &['\u2202']),
- ('\U0001d716', &['\u03f5']), ('\U0001d717', &['\u03d1']), ('\U0001d718', &['\u03f0']),
- ('\U0001d719', &['\u03d5']), ('\U0001d71a', &['\u03f1']), ('\U0001d71b', &['\u03d6']),
- ('\U0001d71c', &['\u0391']), ('\U0001d71d', &['\u0392']), ('\U0001d71e', &['\u0393']),
- ('\U0001d71f', &['\u0394']), ('\U0001d720', &['\u0395']), ('\U0001d721', &['\u0396']),
- ('\U0001d722', &['\u0397']), ('\U0001d723', &['\u0398']), ('\U0001d724', &['\u0399']),
- ('\U0001d725', &['\u039a']), ('\U0001d726', &['\u039b']), ('\U0001d727', &['\u039c']),
- ('\U0001d728', &['\u039d']), ('\U0001d729', &['\u039e']), ('\U0001d72a', &['\u039f']),
- ('\U0001d72b', &['\u03a0']), ('\U0001d72c', &['\u03a1']), ('\U0001d72d', &['\u03f4']),
- ('\U0001d72e', &['\u03a3']), ('\U0001d72f', &['\u03a4']), ('\U0001d730', &['\u03a5']),
- ('\U0001d731', &['\u03a6']), ('\U0001d732', &['\u03a7']), ('\U0001d733', &['\u03a8']),
- ('\U0001d734', &['\u03a9']), ('\U0001d735', &['\u2207']), ('\U0001d736', &['\u03b1']),
- ('\U0001d737', &['\u03b2']), ('\U0001d738', &['\u03b3']), ('\U0001d739', &['\u03b4']),
- ('\U0001d73a', &['\u03b5']), ('\U0001d73b', &['\u03b6']), ('\U0001d73c', &['\u03b7']),
- ('\U0001d73d', &['\u03b8']), ('\U0001d73e', &['\u03b9']), ('\U0001d73f', &['\u03ba']),
- ('\U0001d740', &['\u03bb']), ('\U0001d741', &['\u03bc']), ('\U0001d742', &['\u03bd']),
- ('\U0001d743', &['\u03be']), ('\U0001d744', &['\u03bf']), ('\U0001d745', &['\u03c0']),
- ('\U0001d746', &['\u03c1']), ('\U0001d747', &['\u03c2']), ('\U0001d748', &['\u03c3']),
- ('\U0001d749', &['\u03c4']), ('\U0001d74a', &['\u03c5']), ('\U0001d74b', &['\u03c6']),
- ('\U0001d74c', &['\u03c7']), ('\U0001d74d', &['\u03c8']), ('\U0001d74e', &['\u03c9']),
- ('\U0001d74f', &['\u2202']), ('\U0001d750', &['\u03f5']), ('\U0001d751', &['\u03d1']),
- ('\U0001d752', &['\u03f0']), ('\U0001d753', &['\u03d5']), ('\U0001d754', &['\u03f1']),
- ('\U0001d755', &['\u03d6']), ('\U0001d756', &['\u0391']), ('\U0001d757', &['\u0392']),
- ('\U0001d758', &['\u0393']), ('\U0001d759', &['\u0394']), ('\U0001d75a', &['\u0395']),
- ('\U0001d75b', &['\u0396']), ('\U0001d75c', &['\u0397']), ('\U0001d75d', &['\u0398']),
- ('\U0001d75e', &['\u0399']), ('\U0001d75f', &['\u039a']), ('\U0001d760', &['\u039b']),
- ('\U0001d761', &['\u039c']), ('\U0001d762', &['\u039d']), ('\U0001d763', &['\u039e']),
- ('\U0001d764', &['\u039f']), ('\U0001d765', &['\u03a0']), ('\U0001d766', &['\u03a1']),
- ('\U0001d767', &['\u03f4']), ('\U0001d768', &['\u03a3']), ('\U0001d769', &['\u03a4']),
- ('\U0001d76a', &['\u03a5']), ('\U0001d76b', &['\u03a6']), ('\U0001d76c', &['\u03a7']),
- ('\U0001d76d', &['\u03a8']), ('\U0001d76e', &['\u03a9']), ('\U0001d76f', &['\u2207']),
- ('\U0001d770', &['\u03b1']), ('\U0001d771', &['\u03b2']), ('\U0001d772', &['\u03b3']),
- ('\U0001d773', &['\u03b4']), ('\U0001d774', &['\u03b5']), ('\U0001d775', &['\u03b6']),
- ('\U0001d776', &['\u03b7']), ('\U0001d777', &['\u03b8']), ('\U0001d778', &['\u03b9']),
- ('\U0001d779', &['\u03ba']), ('\U0001d77a', &['\u03bb']), ('\U0001d77b', &['\u03bc']),
- ('\U0001d77c', &['\u03bd']), ('\U0001d77d', &['\u03be']), ('\U0001d77e', &['\u03bf']),
- ('\U0001d77f', &['\u03c0']), ('\U0001d780', &['\u03c1']), ('\U0001d781', &['\u03c2']),
- ('\U0001d782', &['\u03c3']), ('\U0001d783', &['\u03c4']), ('\U0001d784', &['\u03c5']),
- ('\U0001d785', &['\u03c6']), ('\U0001d786', &['\u03c7']), ('\U0001d787', &['\u03c8']),
- ('\U0001d788', &['\u03c9']), ('\U0001d789', &['\u2202']), ('\U0001d78a', &['\u03f5']),
- ('\U0001d78b', &['\u03d1']), ('\U0001d78c', &['\u03f0']), ('\U0001d78d', &['\u03d5']),
- ('\U0001d78e', &['\u03f1']), ('\U0001d78f', &['\u03d6']), ('\U0001d790', &['\u0391']),
- ('\U0001d791', &['\u0392']), ('\U0001d792', &['\u0393']), ('\U0001d793', &['\u0394']),
- ('\U0001d794', &['\u0395']), ('\U0001d795', &['\u0396']), ('\U0001d796', &['\u0397']),
- ('\U0001d797', &['\u0398']), ('\U0001d798', &['\u0399']), ('\U0001d799', &['\u039a']),
- ('\U0001d79a', &['\u039b']), ('\U0001d79b', &['\u039c']), ('\U0001d79c', &['\u039d']),
- ('\U0001d79d', &['\u039e']), ('\U0001d79e', &['\u039f']), ('\U0001d79f', &['\u03a0']),
- ('\U0001d7a0', &['\u03a1']), ('\U0001d7a1', &['\u03f4']), ('\U0001d7a2', &['\u03a3']),
- ('\U0001d7a3', &['\u03a4']), ('\U0001d7a4', &['\u03a5']), ('\U0001d7a5', &['\u03a6']),
- ('\U0001d7a6', &['\u03a7']), ('\U0001d7a7', &['\u03a8']), ('\U0001d7a8', &['\u03a9']),
- ('\U0001d7a9', &['\u2207']), ('\U0001d7aa', &['\u03b1']), ('\U0001d7ab', &['\u03b2']),
- ('\U0001d7ac', &['\u03b3']), ('\U0001d7ad', &['\u03b4']), ('\U0001d7ae', &['\u03b5']),
- ('\U0001d7af', &['\u03b6']), ('\U0001d7b0', &['\u03b7']), ('\U0001d7b1', &['\u03b8']),
- ('\U0001d7b2', &['\u03b9']), ('\U0001d7b3', &['\u03ba']), ('\U0001d7b4', &['\u03bb']),
- ('\U0001d7b5', &['\u03bc']), ('\U0001d7b6', &['\u03bd']), ('\U0001d7b7', &['\u03be']),
- ('\U0001d7b8', &['\u03bf']), ('\U0001d7b9', &['\u03c0']), ('\U0001d7ba', &['\u03c1']),
- ('\U0001d7bb', &['\u03c2']), ('\U0001d7bc', &['\u03c3']), ('\U0001d7bd', &['\u03c4']),
- ('\U0001d7be', &['\u03c5']), ('\U0001d7bf', &['\u03c6']), ('\U0001d7c0', &['\u03c7']),
- ('\U0001d7c1', &['\u03c8']), ('\U0001d7c2', &['\u03c9']), ('\U0001d7c3', &['\u2202']),
- ('\U0001d7c4', &['\u03f5']), ('\U0001d7c5', &['\u03d1']), ('\U0001d7c6', &['\u03f0']),
- ('\U0001d7c7', &['\u03d5']), ('\U0001d7c8', &['\u03f1']), ('\U0001d7c9', &['\u03d6']),
- ('\U0001d7ca', &['\u03dc']), ('\U0001d7cb', &['\u03dd']), ('\U0001d7ce', &['\x30']),
- ('\U0001d7cf', &['\x31']), ('\U0001d7d0', &['\x32']), ('\U0001d7d1', &['\x33']),
- ('\U0001d7d2', &['\x34']), ('\U0001d7d3', &['\x35']), ('\U0001d7d4', &['\x36']),
- ('\U0001d7d5', &['\x37']), ('\U0001d7d6', &['\x38']), ('\U0001d7d7', &['\x39']),
- ('\U0001d7d8', &['\x30']), ('\U0001d7d9', &['\x31']), ('\U0001d7da', &['\x32']),
- ('\U0001d7db', &['\x33']), ('\U0001d7dc', &['\x34']), ('\U0001d7dd', &['\x35']),
- ('\U0001d7de', &['\x36']), ('\U0001d7df', &['\x37']), ('\U0001d7e0', &['\x38']),
- ('\U0001d7e1', &['\x39']), ('\U0001d7e2', &['\x30']), ('\U0001d7e3', &['\x31']),
- ('\U0001d7e4', &['\x32']), ('\U0001d7e5', &['\x33']), ('\U0001d7e6', &['\x34']),
- ('\U0001d7e7', &['\x35']), ('\U0001d7e8', &['\x36']), ('\U0001d7e9', &['\x37']),
- ('\U0001d7ea', &['\x38']), ('\U0001d7eb', &['\x39']), ('\U0001d7ec', &['\x30']),
- ('\U0001d7ed', &['\x31']), ('\U0001d7ee', &['\x32']), ('\U0001d7ef', &['\x33']),
- ('\U0001d7f0', &['\x34']), ('\U0001d7f1', &['\x35']), ('\U0001d7f2', &['\x36']),
- ('\U0001d7f3', &['\x37']), ('\U0001d7f4', &['\x38']), ('\U0001d7f5', &['\x39']),
- ('\U0001d7f6', &['\x30']), ('\U0001d7f7', &['\x31']), ('\U0001d7f8', &['\x32']),
- ('\U0001d7f9', &['\x33']), ('\U0001d7fa', &['\x34']), ('\U0001d7fb', &['\x35']),
- ('\U0001d7fc', &['\x36']), ('\U0001d7fd', &['\x37']), ('\U0001d7fe', &['\x38']),
- ('\U0001d7ff', &['\x39']), ('\U0001ee00', &['\u0627']), ('\U0001ee01', &['\u0628']),
- ('\U0001ee02', &['\u062c']), ('\U0001ee03', &['\u062f']), ('\U0001ee05', &['\u0648']),
- ('\U0001ee06', &['\u0632']), ('\U0001ee07', &['\u062d']), ('\U0001ee08', &['\u0637']),
- ('\U0001ee09', &['\u064a']), ('\U0001ee0a', &['\u0643']), ('\U0001ee0b', &['\u0644']),
- ('\U0001ee0c', &['\u0645']), ('\U0001ee0d', &['\u0646']), ('\U0001ee0e', &['\u0633']),
- ('\U0001ee0f', &['\u0639']), ('\U0001ee10', &['\u0641']), ('\U0001ee11', &['\u0635']),
- ('\U0001ee12', &['\u0642']), ('\U0001ee13', &['\u0631']), ('\U0001ee14', &['\u0634']),
- ('\U0001ee15', &['\u062a']), ('\U0001ee16', &['\u062b']), ('\U0001ee17', &['\u062e']),
- ('\U0001ee18', &['\u0630']), ('\U0001ee19', &['\u0636']), ('\U0001ee1a', &['\u0638']),
- ('\U0001ee1b', &['\u063a']), ('\U0001ee1c', &['\u066e']), ('\U0001ee1d', &['\u06ba']),
- ('\U0001ee1e', &['\u06a1']), ('\U0001ee1f', &['\u066f']), ('\U0001ee21', &['\u0628']),
- ('\U0001ee22', &['\u062c']), ('\U0001ee24', &['\u0647']), ('\U0001ee27', &['\u062d']),
- ('\U0001ee29', &['\u064a']), ('\U0001ee2a', &['\u0643']), ('\U0001ee2b', &['\u0644']),
- ('\U0001ee2c', &['\u0645']), ('\U0001ee2d', &['\u0646']), ('\U0001ee2e', &['\u0633']),
- ('\U0001ee2f', &['\u0639']), ('\U0001ee30', &['\u0641']), ('\U0001ee31', &['\u0635']),
- ('\U0001ee32', &['\u0642']), ('\U0001ee34', &['\u0634']), ('\U0001ee35', &['\u062a']),
- ('\U0001ee36', &['\u062b']), ('\U0001ee37', &['\u062e']), ('\U0001ee39', &['\u0636']),
- ('\U0001ee3b', &['\u063a']), ('\U0001ee42', &['\u062c']), ('\U0001ee47', &['\u062d']),
- ('\U0001ee49', &['\u064a']), ('\U0001ee4b', &['\u0644']), ('\U0001ee4d', &['\u0646']),
- ('\U0001ee4e', &['\u0633']), ('\U0001ee4f', &['\u0639']), ('\U0001ee51', &['\u0635']),
- ('\U0001ee52', &['\u0642']), ('\U0001ee54', &['\u0634']), ('\U0001ee57', &['\u062e']),
- ('\U0001ee59', &['\u0636']), ('\U0001ee5b', &['\u063a']), ('\U0001ee5d', &['\u06ba']),
- ('\U0001ee5f', &['\u066f']), ('\U0001ee61', &['\u0628']), ('\U0001ee62', &['\u062c']),
- ('\U0001ee64', &['\u0647']), ('\U0001ee67', &['\u062d']), ('\U0001ee68', &['\u0637']),
- ('\U0001ee69', &['\u064a']), ('\U0001ee6a', &['\u0643']), ('\U0001ee6c', &['\u0645']),
- ('\U0001ee6d', &['\u0646']), ('\U0001ee6e', &['\u0633']), ('\U0001ee6f', &['\u0639']),
- ('\U0001ee70', &['\u0641']), ('\U0001ee71', &['\u0635']), ('\U0001ee72', &['\u0642']),
- ('\U0001ee74', &['\u0634']), ('\U0001ee75', &['\u062a']), ('\U0001ee76', &['\u062b']),
- ('\U0001ee77', &['\u062e']), ('\U0001ee79', &['\u0636']), ('\U0001ee7a', &['\u0638']),
- ('\U0001ee7b', &['\u063a']), ('\U0001ee7c', &['\u066e']), ('\U0001ee7e', &['\u06a1']),
- ('\U0001ee80', &['\u0627']), ('\U0001ee81', &['\u0628']), ('\U0001ee82', &['\u062c']),
- ('\U0001ee83', &['\u062f']), ('\U0001ee84', &['\u0647']), ('\U0001ee85', &['\u0648']),
- ('\U0001ee86', &['\u0632']), ('\U0001ee87', &['\u062d']), ('\U0001ee88', &['\u0637']),
- ('\U0001ee89', &['\u064a']), ('\U0001ee8b', &['\u0644']), ('\U0001ee8c', &['\u0645']),
- ('\U0001ee8d', &['\u0646']), ('\U0001ee8e', &['\u0633']), ('\U0001ee8f', &['\u0639']),
- ('\U0001ee90', &['\u0641']), ('\U0001ee91', &['\u0635']), ('\U0001ee92', &['\u0642']),
- ('\U0001ee93', &['\u0631']), ('\U0001ee94', &['\u0634']), ('\U0001ee95', &['\u062a']),
- ('\U0001ee96', &['\u062b']), ('\U0001ee97', &['\u062e']), ('\U0001ee98', &['\u0630']),
- ('\U0001ee99', &['\u0636']), ('\U0001ee9a', &['\u0638']), ('\U0001ee9b', &['\u063a']),
- ('\U0001eea1', &['\u0628']), ('\U0001eea2', &['\u062c']), ('\U0001eea3', &['\u062f']),
- ('\U0001eea5', &['\u0648']), ('\U0001eea6', &['\u0632']), ('\U0001eea7', &['\u062d']),
- ('\U0001eea8', &['\u0637']), ('\U0001eea9', &['\u064a']), ('\U0001eeab', &['\u0644']),
- ('\U0001eeac', &['\u0645']), ('\U0001eead', &['\u0646']), ('\U0001eeae', &['\u0633']),
- ('\U0001eeaf', &['\u0639']), ('\U0001eeb0', &['\u0641']), ('\U0001eeb1', &['\u0635']),
- ('\U0001eeb2', &['\u0642']), ('\U0001eeb3', &['\u0631']), ('\U0001eeb4', &['\u0634']),
- ('\U0001eeb5', &['\u062a']), ('\U0001eeb6', &['\u062b']), ('\U0001eeb7', &['\u062e']),
- ('\U0001eeb8', &['\u0630']), ('\U0001eeb9', &['\u0636']), ('\U0001eeba', &['\u0638']),
- ('\U0001eebb', &['\u063a']), ('\U0001f100', &['\x30', '\x2e']), ('\U0001f101', &['\x30',
- '\x2c']), ('\U0001f102', &['\x31', '\x2c']), ('\U0001f103', &['\x32', '\x2c']),
- ('\U0001f104', &['\x33', '\x2c']), ('\U0001f105', &['\x34', '\x2c']), ('\U0001f106',
- &['\x35', '\x2c']), ('\U0001f107', &['\x36', '\x2c']), ('\U0001f108', &['\x37', '\x2c']),
- ('\U0001f109', &['\x38', '\x2c']), ('\U0001f10a', &['\x39', '\x2c']), ('\U0001f110',
- &['\x28', '\x41', '\x29']), ('\U0001f111', &['\x28', '\x42', '\x29']), ('\U0001f112',
- &['\x28', '\x43', '\x29']), ('\U0001f113', &['\x28', '\x44', '\x29']), ('\U0001f114',
- &['\x28', '\x45', '\x29']), ('\U0001f115', &['\x28', '\x46', '\x29']), ('\U0001f116',
- &['\x28', '\x47', '\x29']), ('\U0001f117', &['\x28', '\x48', '\x29']), ('\U0001f118',
- &['\x28', '\x49', '\x29']), ('\U0001f119', &['\x28', '\x4a', '\x29']), ('\U0001f11a',
- &['\x28', '\x4b', '\x29']), ('\U0001f11b', &['\x28', '\x4c', '\x29']), ('\U0001f11c',
- &['\x28', '\x4d', '\x29']), ('\U0001f11d', &['\x28', '\x4e', '\x29']), ('\U0001f11e',
- &['\x28', '\x4f', '\x29']), ('\U0001f11f', &['\x28', '\x50', '\x29']), ('\U0001f120',
- &['\x28', '\x51', '\x29']), ('\U0001f121', &['\x28', '\x52', '\x29']), ('\U0001f122',
- &['\x28', '\x53', '\x29']), ('\U0001f123', &['\x28', '\x54', '\x29']), ('\U0001f124',
- &['\x28', '\x55', '\x29']), ('\U0001f125', &['\x28', '\x56', '\x29']), ('\U0001f126',
- &['\x28', '\x57', '\x29']), ('\U0001f127', &['\x28', '\x58', '\x29']), ('\U0001f128',
- &['\x28', '\x59', '\x29']), ('\U0001f129', &['\x28', '\x5a', '\x29']), ('\U0001f12a',
- &['\u3014', '\x53', '\u3015']), ('\U0001f12b', &['\x43']), ('\U0001f12c', &['\x52']),
- ('\U0001f12d', &['\x43', '\x44']), ('\U0001f12e', &['\x57', '\x5a']), ('\U0001f130',
- &['\x41']), ('\U0001f131', &['\x42']), ('\U0001f132', &['\x43']), ('\U0001f133', &['\x44']),
- ('\U0001f134', &['\x45']), ('\U0001f135', &['\x46']), ('\U0001f136', &['\x47']),
- ('\U0001f137', &['\x48']), ('\U0001f138', &['\x49']), ('\U0001f139', &['\x4a']),
- ('\U0001f13a', &['\x4b']), ('\U0001f13b', &['\x4c']), ('\U0001f13c', &['\x4d']),
- ('\U0001f13d', &['\x4e']), ('\U0001f13e', &['\x4f']), ('\U0001f13f', &['\x50']),
- ('\U0001f140', &['\x51']), ('\U0001f141', &['\x52']), ('\U0001f142', &['\x53']),
- ('\U0001f143', &['\x54']), ('\U0001f144', &['\x55']), ('\U0001f145', &['\x56']),
- ('\U0001f146', &['\x57']), ('\U0001f147', &['\x58']), ('\U0001f148', &['\x59']),
- ('\U0001f149', &['\x5a']), ('\U0001f14a', &['\x48', '\x56']), ('\U0001f14b', &['\x4d',
- '\x56']), ('\U0001f14c', &['\x53', '\x44']), ('\U0001f14d', &['\x53', '\x53']),
- ('\U0001f14e', &['\x50', '\x50', '\x56']), ('\U0001f14f', &['\x57', '\x43']), ('\U0001f16a',
- &['\x4d', '\x43']), ('\U0001f16b', &['\x4d', '\x44']), ('\U0001f190', &['\x44', '\x4a']),
- ('\U0001f200', &['\u307b', '\u304b']), ('\U0001f201', &['\u30b3', '\u30b3']), ('\U0001f202',
- &['\u30b5']), ('\U0001f210', &['\u624b']), ('\U0001f211', &['\u5b57']), ('\U0001f212',
- &['\u53cc']), ('\U0001f213', &['\u30c7']), ('\U0001f214', &['\u4e8c']), ('\U0001f215',
- &['\u591a']), ('\U0001f216', &['\u89e3']), ('\U0001f217', &['\u5929']), ('\U0001f218',
- &['\u4ea4']), ('\U0001f219', &['\u6620']), ('\U0001f21a', &['\u7121']), ('\U0001f21b',
- &['\u6599']), ('\U0001f21c', &['\u524d']), ('\U0001f21d', &['\u5f8c']), ('\U0001f21e',
- &['\u518d']), ('\U0001f21f', &['\u65b0']), ('\U0001f220', &['\u521d']), ('\U0001f221',
- &['\u7d42']), ('\U0001f222', &['\u751f']), ('\U0001f223', &['\u8ca9']), ('\U0001f224',
- &['\u58f0']), ('\U0001f225', &['\u5439']), ('\U0001f226', &['\u6f14']), ('\U0001f227',
- &['\u6295']), ('\U0001f228', &['\u6355']), ('\U0001f229', &['\u4e00']), ('\U0001f22a',
- &['\u4e09']), ('\U0001f22b', &['\u904a']), ('\U0001f22c', &['\u5de6']), ('\U0001f22d',
- &['\u4e2d']), ('\U0001f22e', &['\u53f3']), ('\U0001f22f', &['\u6307']), ('\U0001f230',
- &['\u8d70']), ('\U0001f231', &['\u6253']), ('\U0001f232', &['\u7981']), ('\U0001f233',
- &['\u7a7a']), ('\U0001f234', &['\u5408']), ('\U0001f235', &['\u6e80']), ('\U0001f236',
- &['\u6709']), ('\U0001f237', &['\u6708']), ('\U0001f238', &['\u7533']), ('\U0001f239',
- &['\u5272']), ('\U0001f23a', &['\u55b6']), ('\U0001f240', &['\u3014', '\u672c', '\u3015']),
- ('\U0001f241', &['\u3014', '\u4e09', '\u3015']), ('\U0001f242', &['\u3014', '\u4e8c',
- '\u3015']), ('\U0001f243', &['\u3014', '\u5b89', '\u3015']), ('\U0001f244', &['\u3014',
- '\u70b9', '\u3015']), ('\U0001f245', &['\u3014', '\u6253', '\u3015']), ('\U0001f246',
- &['\u3014', '\u76d7', '\u3015']), ('\U0001f247', &['\u3014', '\u52dd', '\u3015']),
- ('\U0001f248', &['\u3014', '\u6557', '\u3015']), ('\U0001f250', &['\u5f97']), ('\U0001f251',
- &['\u53ef'])
- ];
-
-
- pub fn decompose_canonical(c: char, i: |char|) { d(c, i, false); }
-
- pub fn decompose_compatible(c: char, i: |char|) { d(c, i, true); }
-
- fn d(c: char, i: |char|, k: bool) {
- use iter::Iterator;
-
- // 7-bit ASCII never decomposes
- if c <= '\x7f' { i(c); return; }
-
- // Perform decomposition for Hangul
- if (c as u32) >= S_BASE && (c as u32) < (S_BASE + S_COUNT) {
- decompose_hangul(c, i);
- return;
- }
-
- // First check the canonical decompositions
- match bsearch_table(c, canonical_table) {
- Some(canon) => {
- for x in canon.iter() {
- d(*x, |b| i(b), k);
- }
- return;
- }
- None => ()
- }
-
- // Bottom out if we're not doing compat.
- if !k { i(c); return; }
-
- // Then check the compatibility decompositions
- match bsearch_table(c, compatibility_table) {
- Some(compat) => {
- for x in compat.iter() {
- d(*x, |b| i(b), k);
- }
- return;
- }
- None => ()
- }
-
- // Finally bottom out.
- i(c);
- }
-
- // Constants from Unicode 6.2.0 Section 3.12 Conjoining Jamo Behavior
- static S_BASE: u32 = 0xAC00;
- static L_BASE: u32 = 0x1100;
- static V_BASE: u32 = 0x1161;
- static T_BASE: u32 = 0x11A7;
- static L_COUNT: u32 = 19;
- static V_COUNT: u32 = 21;
- static T_COUNT: u32 = 28;
- static N_COUNT: u32 = (V_COUNT * T_COUNT);
- static S_COUNT: u32 = (L_COUNT * N_COUNT);
-
- // Decompose a precomposed Hangul syllable
- fn decompose_hangul(s: char, f: |char|) {
- use mem::transmute;
-
- let si = s as u32 - S_BASE;
-
- let li = si / N_COUNT;
- unsafe {
- f(transmute(L_BASE + li));
-
- let vi = (si % N_COUNT) / T_COUNT;
- f(transmute(V_BASE + vi));
-
- let ti = si % T_COUNT;
- if ti > 0 {
- f(transmute(T_BASE + ti));
- }
- }
- }
-}
-
-pub mod derived_property {
- static Alphabetic_table : &'static [(char,char)] = &[
- ('\x41', '\x5a'), ('\x61', '\x7a'),
- ('\xaa', '\xaa'), ('\xb5', '\xb5'),
- ('\xba', '\xba'), ('\xc0', '\xd6'),
- ('\xd8', '\xf6'), ('\xf8', '\u01ba'),
- ('\u01bb', '\u01bb'), ('\u01bc', '\u01bf'),
- ('\u01c0', '\u01c3'), ('\u01c4', '\u0293'),
- ('\u0294', '\u0294'), ('\u0295', '\u02af'),
- ('\u02b0', '\u02c1'), ('\u02c6', '\u02d1'),
- ('\u02e0', '\u02e4'), ('\u02ec', '\u02ec'),
- ('\u02ee', '\u02ee'), ('\u0345', '\u0345'),
- ('\u0370', '\u0373'), ('\u0374', '\u0374'),
- ('\u0376', '\u0377'), ('\u037a', '\u037a'),
- ('\u037b', '\u037d'), ('\u0386', '\u0386'),
- ('\u0388', '\u038a'), ('\u038c', '\u038c'),
- ('\u038e', '\u03a1'), ('\u03a3', '\u03f5'),
- ('\u03f7', '\u0481'), ('\u048a', '\u0527'),
- ('\u0531', '\u0556'), ('\u0559', '\u0559'),
- ('\u0561', '\u0587'), ('\u05b0', '\u05bd'),
- ('\u05bf', '\u05bf'), ('\u05c1', '\u05c2'),
- ('\u05c4', '\u05c5'), ('\u05c7', '\u05c7'),
- ('\u05d0', '\u05ea'), ('\u05f0', '\u05f2'),
- ('\u0610', '\u061a'), ('\u0620', '\u063f'),
- ('\u0640', '\u0640'), ('\u0641', '\u064a'),
- ('\u064b', '\u0657'), ('\u0659', '\u065f'),
- ('\u066e', '\u066f'), ('\u0670', '\u0670'),
- ('\u0671', '\u06d3'), ('\u06d5', '\u06d5'),
- ('\u06d6', '\u06dc'), ('\u06e1', '\u06e4'),
- ('\u06e5', '\u06e6'), ('\u06e7', '\u06e8'),
- ('\u06ed', '\u06ed'), ('\u06ee', '\u06ef'),
- ('\u06fa', '\u06fc'), ('\u06ff', '\u06ff'),
- ('\u0710', '\u0710'), ('\u0711', '\u0711'),
- ('\u0712', '\u072f'), ('\u0730', '\u073f'),
- ('\u074d', '\u07a5'), ('\u07a6', '\u07b0'),
- ('\u07b1', '\u07b1'), ('\u07ca', '\u07ea'),
- ('\u07f4', '\u07f5'), ('\u07fa', '\u07fa'),
- ('\u0800', '\u0815'), ('\u0816', '\u0817'),
- ('\u081a', '\u081a'), ('\u081b', '\u0823'),
- ('\u0824', '\u0824'), ('\u0825', '\u0827'),
- ('\u0828', '\u0828'), ('\u0829', '\u082c'),
- ('\u0840', '\u0858'), ('\u08a0', '\u08a0'),
- ('\u08a2', '\u08ac'), ('\u08e4', '\u08e9'),
- ('\u08f0', '\u08fe'), ('\u0900', '\u0902'),
- ('\u0903', '\u0903'), ('\u0904', '\u0939'),
- ('\u093a', '\u093a'), ('\u093b', '\u093b'),
- ('\u093d', '\u093d'), ('\u093e', '\u0940'),
- ('\u0941', '\u0948'), ('\u0949', '\u094c'),
- ('\u094e', '\u094f'), ('\u0950', '\u0950'),
- ('\u0955', '\u0957'), ('\u0958', '\u0961'),
- ('\u0962', '\u0963'), ('\u0971', '\u0971'),
- ('\u0972', '\u0977'), ('\u0979', '\u097f'),
- ('\u0981', '\u0981'), ('\u0982', '\u0983'),
- ('\u0985', '\u098c'), ('\u098f', '\u0990'),
- ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'),
- ('\u09b2', '\u09b2'), ('\u09b6', '\u09b9'),
- ('\u09bd', '\u09bd'), ('\u09be', '\u09c0'),
- ('\u09c1', '\u09c4'), ('\u09c7', '\u09c8'),
- ('\u09cb', '\u09cc'), ('\u09ce', '\u09ce'),
- ('\u09d7', '\u09d7'), ('\u09dc', '\u09dd'),
- ('\u09df', '\u09e1'), ('\u09e2', '\u09e3'),
- ('\u09f0', '\u09f1'), ('\u0a01', '\u0a02'),
- ('\u0a03', '\u0a03'), ('\u0a05', '\u0a0a'),
- ('\u0a0f', '\u0a10'), ('\u0a13', '\u0a28'),
- ('\u0a2a', '\u0a30'), ('\u0a32', '\u0a33'),
- ('\u0a35', '\u0a36'), ('\u0a38', '\u0a39'),
- ('\u0a3e', '\u0a40'), ('\u0a41', '\u0a42'),
- ('\u0a47', '\u0a48'), ('\u0a4b', '\u0a4c'),
- ('\u0a51', '\u0a51'), ('\u0a59', '\u0a5c'),
- ('\u0a5e', '\u0a5e'), ('\u0a70', '\u0a71'),
- ('\u0a72', '\u0a74'), ('\u0a75', '\u0a75'),
- ('\u0a81', '\u0a82'), ('\u0a83', '\u0a83'),
- ('\u0a85', '\u0a8d'), ('\u0a8f', '\u0a91'),
- ('\u0a93', '\u0aa8'), ('\u0aaa', '\u0ab0'),
- ('\u0ab2', '\u0ab3'), ('\u0ab5', '\u0ab9'),
- ('\u0abd', '\u0abd'), ('\u0abe', '\u0ac0'),
- ('\u0ac1', '\u0ac5'), ('\u0ac7', '\u0ac8'),
- ('\u0ac9', '\u0ac9'), ('\u0acb', '\u0acc'),
- ('\u0ad0', '\u0ad0'), ('\u0ae0', '\u0ae1'),
- ('\u0ae2', '\u0ae3'), ('\u0b01', '\u0b01'),
- ('\u0b02', '\u0b03'), ('\u0b05', '\u0b0c'),
- ('\u0b0f', '\u0b10'), ('\u0b13', '\u0b28'),
- ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'),
- ('\u0b35', '\u0b39'), ('\u0b3d', '\u0b3d'),
- ('\u0b3e', '\u0b3e'), ('\u0b3f', '\u0b3f'),
- ('\u0b40', '\u0b40'), ('\u0b41', '\u0b44'),
- ('\u0b47', '\u0b48'), ('\u0b4b', '\u0b4c'),
- ('\u0b56', '\u0b56'), ('\u0b57', '\u0b57'),
- ('\u0b5c', '\u0b5d'), ('\u0b5f', '\u0b61'),
- ('\u0b62', '\u0b63'), ('\u0b71', '\u0b71'),
- ('\u0b82', '\u0b82'), ('\u0b83', '\u0b83'),
- ('\u0b85', '\u0b8a'), ('\u0b8e', '\u0b90'),
- ('\u0b92', '\u0b95'), ('\u0b99', '\u0b9a'),
- ('\u0b9c', '\u0b9c'), ('\u0b9e', '\u0b9f'),
- ('\u0ba3', '\u0ba4'), ('\u0ba8', '\u0baa'),
- ('\u0bae', '\u0bb9'), ('\u0bbe', '\u0bbf'),
- ('\u0bc0', '\u0bc0'), ('\u0bc1', '\u0bc2'),
- ('\u0bc6', '\u0bc8'), ('\u0bca', '\u0bcc'),
- ('\u0bd0', '\u0bd0'), ('\u0bd7', '\u0bd7'),
- ('\u0c01', '\u0c03'), ('\u0c05', '\u0c0c'),
- ('\u0c0e', '\u0c10'), ('\u0c12', '\u0c28'),
- ('\u0c2a', '\u0c33'), ('\u0c35', '\u0c39'),
- ('\u0c3d', '\u0c3d'), ('\u0c3e', '\u0c40'),
- ('\u0c41', '\u0c44'), ('\u0c46', '\u0c48'),
- ('\u0c4a', '\u0c4c'), ('\u0c55', '\u0c56'),
- ('\u0c58', '\u0c59'), ('\u0c60', '\u0c61'),
- ('\u0c62', '\u0c63'), ('\u0c82', '\u0c83'),
- ('\u0c85', '\u0c8c'), ('\u0c8e', '\u0c90'),
- ('\u0c92', '\u0ca8'), ('\u0caa', '\u0cb3'),
- ('\u0cb5', '\u0cb9'), ('\u0cbd', '\u0cbd'),
- ('\u0cbe', '\u0cbe'), ('\u0cbf', '\u0cbf'),
- ('\u0cc0', '\u0cc4'), ('\u0cc6', '\u0cc6'),
- ('\u0cc7', '\u0cc8'), ('\u0cca', '\u0ccb'),
- ('\u0ccc', '\u0ccc'), ('\u0cd5', '\u0cd6'),
- ('\u0cde', '\u0cde'), ('\u0ce0', '\u0ce1'),
- ('\u0ce2', '\u0ce3'), ('\u0cf1', '\u0cf2'),
- ('\u0d02', '\u0d03'), ('\u0d05', '\u0d0c'),
- ('\u0d0e', '\u0d10'), ('\u0d12', '\u0d3a'),
- ('\u0d3d', '\u0d3d'), ('\u0d3e', '\u0d40'),
- ('\u0d41', '\u0d44'), ('\u0d46', '\u0d48'),
- ('\u0d4a', '\u0d4c'), ('\u0d4e', '\u0d4e'),
- ('\u0d57', '\u0d57'), ('\u0d60', '\u0d61'),
- ('\u0d62', '\u0d63'), ('\u0d7a', '\u0d7f'),
- ('\u0d82', '\u0d83'), ('\u0d85', '\u0d96'),
- ('\u0d9a', '\u0db1'), ('\u0db3', '\u0dbb'),
- ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'),
- ('\u0dcf', '\u0dd1'), ('\u0dd2', '\u0dd4'),
- ('\u0dd6', '\u0dd6'), ('\u0dd8', '\u0ddf'),
- ('\u0df2', '\u0df3'), ('\u0e01', '\u0e30'),
- ('\u0e31', '\u0e31'), ('\u0e32', '\u0e33'),
- ('\u0e34', '\u0e3a'), ('\u0e40', '\u0e45'),
- ('\u0e46', '\u0e46'), ('\u0e4d', '\u0e4d'),
- ('\u0e81', '\u0e82'), ('\u0e84', '\u0e84'),
- ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'),
- ('\u0e8d', '\u0e8d'), ('\u0e94', '\u0e97'),
- ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'),
- ('\u0ea5', '\u0ea5'), ('\u0ea7', '\u0ea7'),
- ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'),
- ('\u0eb1', '\u0eb1'), ('\u0eb2', '\u0eb3'),
- ('\u0eb4', '\u0eb9'), ('\u0ebb', '\u0ebc'),
- ('\u0ebd', '\u0ebd'), ('\u0ec0', '\u0ec4'),
- ('\u0ec6', '\u0ec6'), ('\u0ecd', '\u0ecd'),
- ('\u0edc', '\u0edf'), ('\u0f00', '\u0f00'),
- ('\u0f40', '\u0f47'), ('\u0f49', '\u0f6c'),
- ('\u0f71', '\u0f7e'), ('\u0f7f', '\u0f7f'),
- ('\u0f80', '\u0f81'), ('\u0f88', '\u0f8c'),
- ('\u0f8d', '\u0f97'), ('\u0f99', '\u0fbc'),
- ('\u1000', '\u102a'), ('\u102b', '\u102c'),
- ('\u102d', '\u1030'), ('\u1031', '\u1031'),
- ('\u1032', '\u1036'), ('\u1038', '\u1038'),
- ('\u103b', '\u103c'), ('\u103d', '\u103e'),
- ('\u103f', '\u103f'), ('\u1050', '\u1055'),
- ('\u1056', '\u1057'), ('\u1058', '\u1059'),
- ('\u105a', '\u105d'), ('\u105e', '\u1060'),
- ('\u1061', '\u1061'), ('\u1062', '\u1062'),
- ('\u1065', '\u1066'), ('\u1067', '\u1068'),
- ('\u106e', '\u1070'), ('\u1071', '\u1074'),
- ('\u1075', '\u1081'), ('\u1082', '\u1082'),
- ('\u1083', '\u1084'), ('\u1085', '\u1086'),
- ('\u108e', '\u108e'), ('\u109c', '\u109c'),
- ('\u109d', '\u109d'), ('\u10a0', '\u10c5'),
- ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'),
- ('\u10d0', '\u10fa'), ('\u10fc', '\u10fc'),
- ('\u10fd', '\u1248'), ('\u124a', '\u124d'),
- ('\u1250', '\u1256'), ('\u1258', '\u1258'),
- ('\u125a', '\u125d'), ('\u1260', '\u1288'),
- ('\u128a', '\u128d'), ('\u1290', '\u12b0'),
- ('\u12b2', '\u12b5'), ('\u12b8', '\u12be'),
- ('\u12c0', '\u12c0'), ('\u12c2', '\u12c5'),
- ('\u12c8', '\u12d6'), ('\u12d8', '\u1310'),
- ('\u1312', '\u1315'), ('\u1318', '\u135a'),
- ('\u135f', '\u135f'), ('\u1380', '\u138f'),
- ('\u13a0', '\u13f4'), ('\u1401', '\u166c'),
- ('\u166f', '\u167f'), ('\u1681', '\u169a'),
- ('\u16a0', '\u16ea'), ('\u16ee', '\u16f0'),
- ('\u1700', '\u170c'), ('\u170e', '\u1711'),
- ('\u1712', '\u1713'), ('\u1720', '\u1731'),
- ('\u1732', '\u1733'), ('\u1740', '\u1751'),
- ('\u1752', '\u1753'), ('\u1760', '\u176c'),
- ('\u176e', '\u1770'), ('\u1772', '\u1773'),
- ('\u1780', '\u17b3'), ('\u17b6', '\u17b6'),
- ('\u17b7', '\u17bd'), ('\u17be', '\u17c5'),
- ('\u17c6', '\u17c6'), ('\u17c7', '\u17c8'),
- ('\u17d7', '\u17d7'), ('\u17dc', '\u17dc'),
- ('\u1820', '\u1842'), ('\u1843', '\u1843'),
- ('\u1844', '\u1877'), ('\u1880', '\u18a8'),
- ('\u18a9', '\u18a9'), ('\u18aa', '\u18aa'),
- ('\u18b0', '\u18f5'), ('\u1900', '\u191c'),
- ('\u1920', '\u1922'), ('\u1923', '\u1926'),
- ('\u1927', '\u1928'), ('\u1929', '\u192b'),
- ('\u1930', '\u1931'), ('\u1932', '\u1932'),
- ('\u1933', '\u1938'), ('\u1950', '\u196d'),
- ('\u1970', '\u1974'), ('\u1980', '\u19ab'),
- ('\u19b0', '\u19c0'), ('\u19c1', '\u19c7'),
- ('\u19c8', '\u19c9'), ('\u1a00', '\u1a16'),
- ('\u1a17', '\u1a18'), ('\u1a19', '\u1a1a'),
- ('\u1a1b', '\u1a1b'), ('\u1a20', '\u1a54'),
- ('\u1a55', '\u1a55'), ('\u1a56', '\u1a56'),
- ('\u1a57', '\u1a57'), ('\u1a58', '\u1a5e'),
- ('\u1a61', '\u1a61'), ('\u1a62', '\u1a62'),
- ('\u1a63', '\u1a64'), ('\u1a65', '\u1a6c'),
- ('\u1a6d', '\u1a72'), ('\u1a73', '\u1a74'),
- ('\u1aa7', '\u1aa7'), ('\u1b00', '\u1b03'),
- ('\u1b04', '\u1b04'), ('\u1b05', '\u1b33'),
- ('\u1b35', '\u1b35'), ('\u1b36', '\u1b3a'),
- ('\u1b3b', '\u1b3b'), ('\u1b3c', '\u1b3c'),
- ('\u1b3d', '\u1b41'), ('\u1b42', '\u1b42'),
- ('\u1b43', '\u1b43'), ('\u1b45', '\u1b4b'),
- ('\u1b80', '\u1b81'), ('\u1b82', '\u1b82'),
- ('\u1b83', '\u1ba0'), ('\u1ba1', '\u1ba1'),
- ('\u1ba2', '\u1ba5'), ('\u1ba6', '\u1ba7'),
- ('\u1ba8', '\u1ba9'), ('\u1bac', '\u1bad'),
- ('\u1bae', '\u1baf'), ('\u1bba', '\u1be5'),
- ('\u1be7', '\u1be7'), ('\u1be8', '\u1be9'),
- ('\u1bea', '\u1bec'), ('\u1bed', '\u1bed'),
- ('\u1bee', '\u1bee'), ('\u1bef', '\u1bf1'),
- ('\u1c00', '\u1c23'), ('\u1c24', '\u1c2b'),
- ('\u1c2c', '\u1c33'), ('\u1c34', '\u1c35'),
- ('\u1c4d', '\u1c4f'), ('\u1c5a', '\u1c77'),
- ('\u1c78', '\u1c7d'), ('\u1ce9', '\u1cec'),
- ('\u1cee', '\u1cf1'), ('\u1cf2', '\u1cf3'),
- ('\u1cf5', '\u1cf6'), ('\u1d00', '\u1d2b'),
- ('\u1d2c', '\u1d6a'), ('\u1d6b', '\u1d77'),
- ('\u1d78', '\u1d78'), ('\u1d79', '\u1d9a'),
- ('\u1d9b', '\u1dbf'), ('\u1e00', '\u1f15'),
- ('\u1f18', '\u1f1d'), ('\u1f20', '\u1f45'),
- ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'),
- ('\u1f59', '\u1f59'), ('\u1f5b', '\u1f5b'),
- ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'),
- ('\u1f80', '\u1fb4'), ('\u1fb6', '\u1fbc'),
- ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'),
- ('\u1fc6', '\u1fcc'), ('\u1fd0', '\u1fd3'),
- ('\u1fd6', '\u1fdb'), ('\u1fe0', '\u1fec'),
- ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ffc'),
- ('\u2071', '\u2071'), ('\u207f', '\u207f'),
- ('\u2090', '\u209c'), ('\u2102', '\u2102'),
- ('\u2107', '\u2107'), ('\u210a', '\u2113'),
- ('\u2115', '\u2115'), ('\u2119', '\u211d'),
- ('\u2124', '\u2124'), ('\u2126', '\u2126'),
- ('\u2128', '\u2128'), ('\u212a', '\u212d'),
- ('\u212f', '\u2134'), ('\u2135', '\u2138'),
- ('\u2139', '\u2139'), ('\u213c', '\u213f'),
- ('\u2145', '\u2149'), ('\u214e', '\u214e'),
- ('\u2160', '\u2182'), ('\u2183', '\u2184'),
- ('\u2185', '\u2188'), ('\u24b6', '\u24e9'),
- ('\u2c00', '\u2c2e'), ('\u2c30', '\u2c5e'),
- ('\u2c60', '\u2c7b'), ('\u2c7c', '\u2c7d'),
- ('\u2c7e', '\u2ce4'), ('\u2ceb', '\u2cee'),
- ('\u2cf2', '\u2cf3'), ('\u2d00', '\u2d25'),
- ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'),
- ('\u2d30', '\u2d67'), ('\u2d6f', '\u2d6f'),
- ('\u2d80', '\u2d96'), ('\u2da0', '\u2da6'),
- ('\u2da8', '\u2dae'), ('\u2db0', '\u2db6'),
- ('\u2db8', '\u2dbe'), ('\u2dc0', '\u2dc6'),
- ('\u2dc8', '\u2dce'), ('\u2dd0', '\u2dd6'),
- ('\u2dd8', '\u2dde'), ('\u2de0', '\u2dff'),
- ('\u2e2f', '\u2e2f'), ('\u3005', '\u3005'),
- ('\u3006', '\u3006'), ('\u3007', '\u3007'),
- ('\u3021', '\u3029'), ('\u3031', '\u3035'),
- ('\u3038', '\u303a'), ('\u303b', '\u303b'),
- ('\u303c', '\u303c'), ('\u3041', '\u3096'),
- ('\u309d', '\u309e'), ('\u309f', '\u309f'),
- ('\u30a1', '\u30fa'), ('\u30fc', '\u30fe'),
- ('\u30ff', '\u30ff'), ('\u3105', '\u312d'),
- ('\u3131', '\u318e'), ('\u31a0', '\u31ba'),
- ('\u31f0', '\u31ff'), ('\u3400', '\u4db5'),
- ('\u4e00', '\u9fcc'), ('\ua000', '\ua014'),
- ('\ua015', '\ua015'), ('\ua016', '\ua48c'),
- ('\ua4d0', '\ua4f7'), ('\ua4f8', '\ua4fd'),
- ('\ua500', '\ua60b'), ('\ua60c', '\ua60c'),
- ('\ua610', '\ua61f'), ('\ua62a', '\ua62b'),
- ('\ua640', '\ua66d'), ('\ua66e', '\ua66e'),
- ('\ua674', '\ua67b'), ('\ua67f', '\ua67f'),
- ('\ua680', '\ua697'), ('\ua69f', '\ua69f'),
- ('\ua6a0', '\ua6e5'), ('\ua6e6', '\ua6ef'),
- ('\ua717', '\ua71f'), ('\ua722', '\ua76f'),
- ('\ua770', '\ua770'), ('\ua771', '\ua787'),
- ('\ua788', '\ua788'), ('\ua78b', '\ua78e'),
- ('\ua790', '\ua793'), ('\ua7a0', '\ua7aa'),
- ('\ua7f8', '\ua7f9'), ('\ua7fa', '\ua7fa'),
- ('\ua7fb', '\ua801'), ('\ua803', '\ua805'),
- ('\ua807', '\ua80a'), ('\ua80c', '\ua822'),
- ('\ua823', '\ua824'), ('\ua825', '\ua826'),
- ('\ua827', '\ua827'), ('\ua840', '\ua873'),
- ('\ua880', '\ua881'), ('\ua882', '\ua8b3'),
- ('\ua8b4', '\ua8c3'), ('\ua8f2', '\ua8f7'),
- ('\ua8fb', '\ua8fb'), ('\ua90a', '\ua925'),
- ('\ua926', '\ua92a'), ('\ua930', '\ua946'),
- ('\ua947', '\ua951'), ('\ua952', '\ua952'),
- ('\ua960', '\ua97c'), ('\ua980', '\ua982'),
- ('\ua983', '\ua983'), ('\ua984', '\ua9b2'),
- ('\ua9b4', '\ua9b5'), ('\ua9b6', '\ua9b9'),
- ('\ua9ba', '\ua9bb'), ('\ua9bc', '\ua9bc'),
- ('\ua9bd', '\ua9bf'), ('\ua9cf', '\ua9cf'),
- ('\uaa00', '\uaa28'), ('\uaa29', '\uaa2e'),
- ('\uaa2f', '\uaa30'), ('\uaa31', '\uaa32'),
- ('\uaa33', '\uaa34'), ('\uaa35', '\uaa36'),
- ('\uaa40', '\uaa42'), ('\uaa43', '\uaa43'),
- ('\uaa44', '\uaa4b'), ('\uaa4c', '\uaa4c'),
- ('\uaa4d', '\uaa4d'), ('\uaa60', '\uaa6f'),
- ('\uaa70', '\uaa70'), ('\uaa71', '\uaa76'),
- ('\uaa7a', '\uaa7a'), ('\uaa80', '\uaaaf'),
- ('\uaab0', '\uaab0'), ('\uaab1', '\uaab1'),
- ('\uaab2', '\uaab4'), ('\uaab5', '\uaab6'),
- ('\uaab7', '\uaab8'), ('\uaab9', '\uaabd'),
- ('\uaabe', '\uaabe'), ('\uaac0', '\uaac0'),
- ('\uaac2', '\uaac2'), ('\uaadb', '\uaadc'),
- ('\uaadd', '\uaadd'), ('\uaae0', '\uaaea'),
- ('\uaaeb', '\uaaeb'), ('\uaaec', '\uaaed'),
- ('\uaaee', '\uaaef'), ('\uaaf2', '\uaaf2'),
- ('\uaaf3', '\uaaf4'), ('\uaaf5', '\uaaf5'),
- ('\uab01', '\uab06'), ('\uab09', '\uab0e'),
- ('\uab11', '\uab16'), ('\uab20', '\uab26'),
- ('\uab28', '\uab2e'), ('\uabc0', '\uabe2'),
- ('\uabe3', '\uabe4'), ('\uabe5', '\uabe5'),
- ('\uabe6', '\uabe7'), ('\uabe8', '\uabe8'),
- ('\uabe9', '\uabea'), ('\uac00', '\ud7a3'),
- ('\ud7b0', '\ud7c6'), ('\ud7cb', '\ud7fb'),
- ('\uf900', '\ufa6d'), ('\ufa70', '\ufad9'),
- ('\ufb00', '\ufb06'), ('\ufb13', '\ufb17'),
- ('\ufb1d', '\ufb1d'), ('\ufb1e', '\ufb1e'),
- ('\ufb1f', '\ufb28'), ('\ufb2a', '\ufb36'),
- ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'),
- ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'),
- ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufd3d'),
- ('\ufd50', '\ufd8f'), ('\ufd92', '\ufdc7'),
- ('\ufdf0', '\ufdfb'), ('\ufe70', '\ufe74'),
- ('\ufe76', '\ufefc'), ('\uff21', '\uff3a'),
- ('\uff41', '\uff5a'), ('\uff66', '\uff6f'),
- ('\uff70', '\uff70'), ('\uff71', '\uff9d'),
- ('\uff9e', '\uff9f'), ('\uffa0', '\uffbe'),
- ('\uffc2', '\uffc7'), ('\uffca', '\uffcf'),
- ('\uffd2', '\uffd7'), ('\uffda', '\uffdc'),
- ('\U00010000', '\U0001000b'), ('\U0001000d', '\U00010026'),
- ('\U00010028', '\U0001003a'), ('\U0001003c', '\U0001003d'),
- ('\U0001003f', '\U0001004d'), ('\U00010050', '\U0001005d'),
- ('\U00010080', '\U000100fa'), ('\U00010140', '\U00010174'),
- ('\U00010280', '\U0001029c'), ('\U000102a0', '\U000102d0'),
- ('\U00010300', '\U0001031e'), ('\U00010330', '\U00010340'),
- ('\U00010341', '\U00010341'), ('\U00010342', '\U00010349'),
- ('\U0001034a', '\U0001034a'), ('\U00010380', '\U0001039d'),
- ('\U000103a0', '\U000103c3'), ('\U000103c8', '\U000103cf'),
- ('\U000103d1', '\U000103d5'), ('\U00010400', '\U0001044f'),
- ('\U00010450', '\U0001049d'), ('\U00010800', '\U00010805'),
- ('\U00010808', '\U00010808'), ('\U0001080a', '\U00010835'),
- ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'),
- ('\U0001083f', '\U00010855'), ('\U00010900', '\U00010915'),
- ('\U00010920', '\U00010939'), ('\U00010980', '\U000109b7'),
- ('\U000109be', '\U000109bf'), ('\U00010a00', '\U00010a00'),
- ('\U00010a01', '\U00010a03'), ('\U00010a05', '\U00010a06'),
- ('\U00010a0c', '\U00010a0f'), ('\U00010a10', '\U00010a13'),
- ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'),
- ('\U00010a60', '\U00010a7c'), ('\U00010b00', '\U00010b35'),
- ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'),
- ('\U00010c00', '\U00010c48'), ('\U00011000', '\U00011000'),
- ('\U00011001', '\U00011001'), ('\U00011002', '\U00011002'),
- ('\U00011003', '\U00011037'), ('\U00011038', '\U00011045'),
- ('\U00011082', '\U00011082'), ('\U00011083', '\U000110af'),
- ('\U000110b0', '\U000110b2'), ('\U000110b3', '\U000110b6'),
- ('\U000110b7', '\U000110b8'), ('\U000110d0', '\U000110e8'),
- ('\U00011100', '\U00011102'), ('\U00011103', '\U00011126'),
- ('\U00011127', '\U0001112b'), ('\U0001112c', '\U0001112c'),
- ('\U0001112d', '\U00011132'), ('\U00011180', '\U00011181'),
- ('\U00011182', '\U00011182'), ('\U00011183', '\U000111b2'),
- ('\U000111b3', '\U000111b5'), ('\U000111b6', '\U000111be'),
- ('\U000111bf', '\U000111bf'), ('\U000111c1', '\U000111c4'),
- ('\U00011680', '\U000116aa'), ('\U000116ab', '\U000116ab'),
- ('\U000116ac', '\U000116ac'), ('\U000116ad', '\U000116ad'),
- ('\U000116ae', '\U000116af'), ('\U000116b0', '\U000116b5'),
- ('\U00012000', '\U0001236e'), ('\U00012400', '\U00012462'),
- ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'),
- ('\U00016f00', '\U00016f44'), ('\U00016f50', '\U00016f50'),
- ('\U00016f51', '\U00016f7e'), ('\U00016f93', '\U00016f9f'),
- ('\U0001b000', '\U0001b001'), ('\U0001d400', '\U0001d454'),
- ('\U0001d456', '\U0001d49c'), ('\U0001d49e', '\U0001d49f'),
- ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5', '\U0001d4a6'),
- ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b9'),
- ('\U0001d4bb', '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'),
- ('\U0001d4c5', '\U0001d505'), ('\U0001d507', '\U0001d50a'),
- ('\U0001d50d', '\U0001d514'), ('\U0001d516', '\U0001d51c'),
- ('\U0001d51e', '\U0001d539'), ('\U0001d53b', '\U0001d53e'),
- ('\U0001d540', '\U0001d544'), ('\U0001d546', '\U0001d546'),
- ('\U0001d54a', '\U0001d550'), ('\U0001d552', '\U0001d6a5'),
- ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6c2', '\U0001d6da'),
- ('\U0001d6dc', '\U0001d6fa'), ('\U0001d6fc', '\U0001d714'),
- ('\U0001d716', '\U0001d734'), ('\U0001d736', '\U0001d74e'),
- ('\U0001d750', '\U0001d76e'), ('\U0001d770', '\U0001d788'),
- ('\U0001d78a', '\U0001d7a8'), ('\U0001d7aa', '\U0001d7c2'),
- ('\U0001d7c4', '\U0001d7cb'), ('\U0001ee00', '\U0001ee03'),
- ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'),
- ('\U0001ee24', '\U0001ee24'), ('\U0001ee27', '\U0001ee27'),
- ('\U0001ee29', '\U0001ee32'), ('\U0001ee34', '\U0001ee37'),
- ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'),
- ('\U0001ee42', '\U0001ee42'), ('\U0001ee47', '\U0001ee47'),
- ('\U0001ee49', '\U0001ee49'), ('\U0001ee4b', '\U0001ee4b'),
- ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'),
- ('\U0001ee54', '\U0001ee54'), ('\U0001ee57', '\U0001ee57'),
- ('\U0001ee59', '\U0001ee59'), ('\U0001ee5b', '\U0001ee5b'),
- ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'),
- ('\U0001ee61', '\U0001ee62'), ('\U0001ee64', '\U0001ee64'),
- ('\U0001ee67', '\U0001ee6a'), ('\U0001ee6c', '\U0001ee72'),
- ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'),
- ('\U0001ee7e', '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'),
- ('\U0001ee8b', '\U0001ee9b'), ('\U0001eea1', '\U0001eea3'),
- ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'),
- ('\U00020000', '\U0002a6d6'), ('\U0002a700', '\U0002b734'),
- ('\U0002b740', '\U0002b81d'), ('\U0002f800', '\U0002fa1d')
- ];
-
- pub fn Alphabetic(c: char) -> bool {
- super::bsearch_range_table(c, Alphabetic_table)
- }
-
- static Lowercase_table : &'static [(char,char)] = &[
- ('\x61', '\x7a'), ('\xaa', '\xaa'),
- ('\xb5', '\xb5'), ('\xba', '\xba'),
- ('\xdf', '\xf6'), ('\xf8', '\xff'),
- ('\u0101', '\u0101'), ('\u0103', '\u0103'),
- ('\u0105', '\u0105'), ('\u0107', '\u0107'),
- ('\u0109', '\u0109'), ('\u010b', '\u010b'),
- ('\u010d', '\u010d'), ('\u010f', '\u010f'),
- ('\u0111', '\u0111'), ('\u0113', '\u0113'),
- ('\u0115', '\u0115'), ('\u0117', '\u0117'),
- ('\u0119', '\u0119'), ('\u011b', '\u011b'),
- ('\u011d', '\u011d'), ('\u011f', '\u011f'),
- ('\u0121', '\u0121'), ('\u0123', '\u0123'),
- ('\u0125', '\u0125'), ('\u0127', '\u0127'),
- ('\u0129', '\u0129'), ('\u012b', '\u012b'),
- ('\u012d', '\u012d'), ('\u012f', '\u012f'),
- ('\u0131', '\u0131'), ('\u0133', '\u0133'),
- ('\u0135', '\u0135'), ('\u0137', '\u0138'),
- ('\u013a', '\u013a'), ('\u013c', '\u013c'),
- ('\u013e', '\u013e'), ('\u0140', '\u0140'),
- ('\u0142', '\u0142'), ('\u0144', '\u0144'),
- ('\u0146', '\u0146'), ('\u0148', '\u0149'),
- ('\u014b', '\u014b'), ('\u014d', '\u014d'),
- ('\u014f', '\u014f'), ('\u0151', '\u0151'),
- ('\u0153', '\u0153'), ('\u0155', '\u0155'),
- ('\u0157', '\u0157'), ('\u0159', '\u0159'),
- ('\u015b', '\u015b'), ('\u015d', '\u015d'),
- ('\u015f', '\u015f'), ('\u0161', '\u0161'),
- ('\u0163', '\u0163'), ('\u0165', '\u0165'),
- ('\u0167', '\u0167'), ('\u0169', '\u0169'),
- ('\u016b', '\u016b'), ('\u016d', '\u016d'),
- ('\u016f', '\u016f'), ('\u0171', '\u0171'),
- ('\u0173', '\u0173'), ('\u0175', '\u0175'),
- ('\u0177', '\u0177'), ('\u017a', '\u017a'),
- ('\u017c', '\u017c'), ('\u017e', '\u0180'),
- ('\u0183', '\u0183'), ('\u0185', '\u0185'),
- ('\u0188', '\u0188'), ('\u018c', '\u018d'),
- ('\u0192', '\u0192'), ('\u0195', '\u0195'),
- ('\u0199', '\u019b'), ('\u019e', '\u019e'),
- ('\u01a1', '\u01a1'), ('\u01a3', '\u01a3'),
- ('\u01a5', '\u01a5'), ('\u01a8', '\u01a8'),
- ('\u01aa', '\u01ab'), ('\u01ad', '\u01ad'),
- ('\u01b0', '\u01b0'), ('\u01b4', '\u01b4'),
- ('\u01b6', '\u01b6'), ('\u01b9', '\u01ba'),
- ('\u01bd', '\u01bf'), ('\u01c6', '\u01c6'),
- ('\u01c9', '\u01c9'), ('\u01cc', '\u01cc'),
- ('\u01ce', '\u01ce'), ('\u01d0', '\u01d0'),
- ('\u01d2', '\u01d2'), ('\u01d4', '\u01d4'),
- ('\u01d6', '\u01d6'), ('\u01d8', '\u01d8'),
- ('\u01da', '\u01da'), ('\u01dc', '\u01dd'),
- ('\u01df', '\u01df'), ('\u01e1', '\u01e1'),
- ('\u01e3', '\u01e3'), ('\u01e5', '\u01e5'),
- ('\u01e7', '\u01e7'), ('\u01e9', '\u01e9'),
- ('\u01eb', '\u01eb'), ('\u01ed', '\u01ed'),
- ('\u01ef', '\u01f0'), ('\u01f3', '\u01f3'),
- ('\u01f5', '\u01f5'), ('\u01f9', '\u01f9'),
- ('\u01fb', '\u01fb'), ('\u01fd', '\u01fd'),
- ('\u01ff', '\u01ff'), ('\u0201', '\u0201'),
- ('\u0203', '\u0203'), ('\u0205', '\u0205'),
- ('\u0207', '\u0207'), ('\u0209', '\u0209'),
- ('\u020b', '\u020b'), ('\u020d', '\u020d'),
- ('\u020f', '\u020f'), ('\u0211', '\u0211'),
- ('\u0213', '\u0213'), ('\u0215', '\u0215'),
- ('\u0217', '\u0217'), ('\u0219', '\u0219'),
- ('\u021b', '\u021b'), ('\u021d', '\u021d'),
- ('\u021f', '\u021f'), ('\u0221', '\u0221'),
- ('\u0223', '\u0223'), ('\u0225', '\u0225'),
- ('\u0227', '\u0227'), ('\u0229', '\u0229'),
- ('\u022b', '\u022b'), ('\u022d', '\u022d'),
- ('\u022f', '\u022f'), ('\u0231', '\u0231'),
- ('\u0233', '\u0239'), ('\u023c', '\u023c'),
- ('\u023f', '\u0240'), ('\u0242', '\u0242'),
- ('\u0247', '\u0247'), ('\u0249', '\u0249'),
- ('\u024b', '\u024b'), ('\u024d', '\u024d'),
- ('\u024f', '\u0293'), ('\u0295', '\u02af'),
- ('\u02b0', '\u02b8'), ('\u02c0', '\u02c1'),
- ('\u02e0', '\u02e4'), ('\u0345', '\u0345'),
- ('\u0371', '\u0371'), ('\u0373', '\u0373'),
- ('\u0377', '\u0377'), ('\u037a', '\u037a'),
- ('\u037b', '\u037d'), ('\u0390', '\u0390'),
- ('\u03ac', '\u03ce'), ('\u03d0', '\u03d1'),
- ('\u03d5', '\u03d7'), ('\u03d9', '\u03d9'),
- ('\u03db', '\u03db'), ('\u03dd', '\u03dd'),
- ('\u03df', '\u03df'), ('\u03e1', '\u03e1'),
- ('\u03e3', '\u03e3'), ('\u03e5', '\u03e5'),
- ('\u03e7', '\u03e7'), ('\u03e9', '\u03e9'),
- ('\u03eb', '\u03eb'), ('\u03ed', '\u03ed'),
- ('\u03ef', '\u03f3'), ('\u03f5', '\u03f5'),
- ('\u03f8', '\u03f8'), ('\u03fb', '\u03fc'),
- ('\u0430', '\u045f'), ('\u0461', '\u0461'),
- ('\u0463', '\u0463'), ('\u0465', '\u0465'),
- ('\u0467', '\u0467'), ('\u0469', '\u0469'),
- ('\u046b', '\u046b'), ('\u046d', '\u046d'),
- ('\u046f', '\u046f'), ('\u0471', '\u0471'),
- ('\u0473', '\u0473'), ('\u0475', '\u0475'),
- ('\u0477', '\u0477'), ('\u0479', '\u0479'),
- ('\u047b', '\u047b'), ('\u047d', '\u047d'),
- ('\u047f', '\u047f'), ('\u0481', '\u0481'),
- ('\u048b', '\u048b'), ('\u048d', '\u048d'),
- ('\u048f', '\u048f'), ('\u0491', '\u0491'),
- ('\u0493', '\u0493'), ('\u0495', '\u0495'),
- ('\u0497', '\u0497'), ('\u0499', '\u0499'),
- ('\u049b', '\u049b'), ('\u049d', '\u049d'),
- ('\u049f', '\u049f'), ('\u04a1', '\u04a1'),
- ('\u04a3', '\u04a3'), ('\u04a5', '\u04a5'),
- ('\u04a7', '\u04a7'), ('\u04a9', '\u04a9'),
- ('\u04ab', '\u04ab'), ('\u04ad', '\u04ad'),
- ('\u04af', '\u04af'), ('\u04b1', '\u04b1'),
- ('\u04b3', '\u04b3'), ('\u04b5', '\u04b5'),
- ('\u04b7', '\u04b7'), ('\u04b9', '\u04b9'),
- ('\u04bb', '\u04bb'), ('\u04bd', '\u04bd'),
- ('\u04bf', '\u04bf'), ('\u04c2', '\u04c2'),
- ('\u04c4', '\u04c4'), ('\u04c6', '\u04c6'),
- ('\u04c8', '\u04c8'), ('\u04ca', '\u04ca'),
- ('\u04cc', '\u04cc'), ('\u04ce', '\u04cf'),
- ('\u04d1', '\u04d1'), ('\u04d3', '\u04d3'),
- ('\u04d5', '\u04d5'), ('\u04d7', '\u04d7'),
- ('\u04d9', '\u04d9'), ('\u04db', '\u04db'),
- ('\u04dd', '\u04dd'), ('\u04df', '\u04df'),
- ('\u04e1', '\u04e1'), ('\u04e3', '\u04e3'),
- ('\u04e5', '\u04e5'), ('\u04e7', '\u04e7'),
- ('\u04e9', '\u04e9'), ('\u04eb', '\u04eb'),
- ('\u04ed', '\u04ed'), ('\u04ef', '\u04ef'),
- ('\u04f1', '\u04f1'), ('\u04f3', '\u04f3'),
- ('\u04f5', '\u04f5'), ('\u04f7', '\u04f7'),
- ('\u04f9', '\u04f9'), ('\u04fb', '\u04fb'),
- ('\u04fd', '\u04fd'), ('\u04ff', '\u04ff'),
- ('\u0501', '\u0501'), ('\u0503', '\u0503'),
- ('\u0505', '\u0505'), ('\u0507', '\u0507'),
- ('\u0509', '\u0509'), ('\u050b', '\u050b'),
- ('\u050d', '\u050d'), ('\u050f', '\u050f'),
- ('\u0511', '\u0511'), ('\u0513', '\u0513'),
- ('\u0515', '\u0515'), ('\u0517', '\u0517'),
- ('\u0519', '\u0519'), ('\u051b', '\u051b'),
- ('\u051d', '\u051d'), ('\u051f', '\u051f'),
- ('\u0521', '\u0521'), ('\u0523', '\u0523'),
- ('\u0525', '\u0525'), ('\u0527', '\u0527'),
- ('\u0561', '\u0587'), ('\u1d00', '\u1d2b'),
- ('\u1d2c', '\u1d6a'), ('\u1d6b', '\u1d77'),
- ('\u1d78', '\u1d78'), ('\u1d79', '\u1d9a'),
- ('\u1d9b', '\u1dbf'), ('\u1e01', '\u1e01'),
- ('\u1e03', '\u1e03'), ('\u1e05', '\u1e05'),
- ('\u1e07', '\u1e07'), ('\u1e09', '\u1e09'),
- ('\u1e0b', '\u1e0b'), ('\u1e0d', '\u1e0d'),
- ('\u1e0f', '\u1e0f'), ('\u1e11', '\u1e11'),
- ('\u1e13', '\u1e13'), ('\u1e15', '\u1e15'),
- ('\u1e17', '\u1e17'), ('\u1e19', '\u1e19'),
- ('\u1e1b', '\u1e1b'), ('\u1e1d', '\u1e1d'),
- ('\u1e1f', '\u1e1f'), ('\u1e21', '\u1e21'),
- ('\u1e23', '\u1e23'), ('\u1e25', '\u1e25'),
- ('\u1e27', '\u1e27'), ('\u1e29', '\u1e29'),
- ('\u1e2b', '\u1e2b'), ('\u1e2d', '\u1e2d'),
- ('\u1e2f', '\u1e2f'), ('\u1e31', '\u1e31'),
- ('\u1e33', '\u1e33'), ('\u1e35', '\u1e35'),
- ('\u1e37', '\u1e37'), ('\u1e39', '\u1e39'),
- ('\u1e3b', '\u1e3b'), ('\u1e3d', '\u1e3d'),
- ('\u1e3f', '\u1e3f'), ('\u1e41', '\u1e41'),
- ('\u1e43', '\u1e43'), ('\u1e45', '\u1e45'),
- ('\u1e47', '\u1e47'), ('\u1e49', '\u1e49'),
- ('\u1e4b', '\u1e4b'), ('\u1e4d', '\u1e4d'),
- ('\u1e4f', '\u1e4f'), ('\u1e51', '\u1e51'),
- ('\u1e53', '\u1e53'), ('\u1e55', '\u1e55'),
- ('\u1e57', '\u1e57'), ('\u1e59', '\u1e59'),
- ('\u1e5b', '\u1e5b'), ('\u1e5d', '\u1e5d'),
- ('\u1e5f', '\u1e5f'), ('\u1e61', '\u1e61'),
- ('\u1e63', '\u1e63'), ('\u1e65', '\u1e65'),
- ('\u1e67', '\u1e67'), ('\u1e69', '\u1e69'),
- ('\u1e6b', '\u1e6b'), ('\u1e6d', '\u1e6d'),
- ('\u1e6f', '\u1e6f'), ('\u1e71', '\u1e71'),
- ('\u1e73', '\u1e73'), ('\u1e75', '\u1e75'),
- ('\u1e77', '\u1e77'), ('\u1e79', '\u1e79'),
- ('\u1e7b', '\u1e7b'), ('\u1e7d', '\u1e7d'),
- ('\u1e7f', '\u1e7f'), ('\u1e81', '\u1e81'),
- ('\u1e83', '\u1e83'), ('\u1e85', '\u1e85'),
- ('\u1e87', '\u1e87'), ('\u1e89', '\u1e89'),
- ('\u1e8b', '\u1e8b'), ('\u1e8d', '\u1e8d'),
- ('\u1e8f', '\u1e8f'), ('\u1e91', '\u1e91'),
- ('\u1e93', '\u1e93'), ('\u1e95', '\u1e9d'),
- ('\u1e9f', '\u1e9f'), ('\u1ea1', '\u1ea1'),
- ('\u1ea3', '\u1ea3'), ('\u1ea5', '\u1ea5'),
- ('\u1ea7', '\u1ea7'), ('\u1ea9', '\u1ea9'),
- ('\u1eab', '\u1eab'), ('\u1ead', '\u1ead'),
- ('\u1eaf', '\u1eaf'), ('\u1eb1', '\u1eb1'),
- ('\u1eb3', '\u1eb3'), ('\u1eb5', '\u1eb5'),
- ('\u1eb7', '\u1eb7'), ('\u1eb9', '\u1eb9'),
- ('\u1ebb', '\u1ebb'), ('\u1ebd', '\u1ebd'),
- ('\u1ebf', '\u1ebf'), ('\u1ec1', '\u1ec1'),
- ('\u1ec3', '\u1ec3'), ('\u1ec5', '\u1ec5'),
- ('\u1ec7', '\u1ec7'), ('\u1ec9', '\u1ec9'),
- ('\u1ecb', '\u1ecb'), ('\u1ecd', '\u1ecd'),
- ('\u1ecf', '\u1ecf'), ('\u1ed1', '\u1ed1'),
- ('\u1ed3', '\u1ed3'), ('\u1ed5', '\u1ed5'),
- ('\u1ed7', '\u1ed7'), ('\u1ed9', '\u1ed9'),
- ('\u1edb', '\u1edb'), ('\u1edd', '\u1edd'),
- ('\u1edf', '\u1edf'), ('\u1ee1', '\u1ee1'),
- ('\u1ee3', '\u1ee3'), ('\u1ee5', '\u1ee5'),
- ('\u1ee7', '\u1ee7'), ('\u1ee9', '\u1ee9'),
- ('\u1eeb', '\u1eeb'), ('\u1eed', '\u1eed'),
- ('\u1eef', '\u1eef'), ('\u1ef1', '\u1ef1'),
- ('\u1ef3', '\u1ef3'), ('\u1ef5', '\u1ef5'),
- ('\u1ef7', '\u1ef7'), ('\u1ef9', '\u1ef9'),
- ('\u1efb', '\u1efb'), ('\u1efd', '\u1efd'),
- ('\u1eff', '\u1f07'), ('\u1f10', '\u1f15'),
- ('\u1f20', '\u1f27'), ('\u1f30', '\u1f37'),
- ('\u1f40', '\u1f45'), ('\u1f50', '\u1f57'),
- ('\u1f60', '\u1f67'), ('\u1f70', '\u1f7d'),
- ('\u1f80', '\u1f87'), ('\u1f90', '\u1f97'),
- ('\u1fa0', '\u1fa7'), ('\u1fb0', '\u1fb4'),
- ('\u1fb6', '\u1fb7'), ('\u1fbe', '\u1fbe'),
- ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fc7'),
- ('\u1fd0', '\u1fd3'), ('\u1fd6', '\u1fd7'),
- ('\u1fe0', '\u1fe7'), ('\u1ff2', '\u1ff4'),
- ('\u1ff6', '\u1ff7'), ('\u2071', '\u2071'),
- ('\u207f', '\u207f'), ('\u2090', '\u209c'),
- ('\u210a', '\u210a'), ('\u210e', '\u210f'),
- ('\u2113', '\u2113'), ('\u212f', '\u212f'),
- ('\u2134', '\u2134'), ('\u2139', '\u2139'),
- ('\u213c', '\u213d'), ('\u2146', '\u2149'),
- ('\u214e', '\u214e'), ('\u2170', '\u217f'),
- ('\u2184', '\u2184'), ('\u24d0', '\u24e9'),
- ('\u2c30', '\u2c5e'), ('\u2c61', '\u2c61'),
- ('\u2c65', '\u2c66'), ('\u2c68', '\u2c68'),
- ('\u2c6a', '\u2c6a'), ('\u2c6c', '\u2c6c'),
- ('\u2c71', '\u2c71'), ('\u2c73', '\u2c74'),
- ('\u2c76', '\u2c7b'), ('\u2c7c', '\u2c7d'),
- ('\u2c81', '\u2c81'), ('\u2c83', '\u2c83'),
- ('\u2c85', '\u2c85'), ('\u2c87', '\u2c87'),
- ('\u2c89', '\u2c89'), ('\u2c8b', '\u2c8b'),
- ('\u2c8d', '\u2c8d'), ('\u2c8f', '\u2c8f'),
- ('\u2c91', '\u2c91'), ('\u2c93', '\u2c93'),
- ('\u2c95', '\u2c95'), ('\u2c97', '\u2c97'),
- ('\u2c99', '\u2c99'), ('\u2c9b', '\u2c9b'),
- ('\u2c9d', '\u2c9d'), ('\u2c9f', '\u2c9f'),
- ('\u2ca1', '\u2ca1'), ('\u2ca3', '\u2ca3'),
- ('\u2ca5', '\u2ca5'), ('\u2ca7', '\u2ca7'),
- ('\u2ca9', '\u2ca9'), ('\u2cab', '\u2cab'),
- ('\u2cad', '\u2cad'), ('\u2caf', '\u2caf'),
- ('\u2cb1', '\u2cb1'), ('\u2cb3', '\u2cb3'),
- ('\u2cb5', '\u2cb5'), ('\u2cb7', '\u2cb7'),
- ('\u2cb9', '\u2cb9'), ('\u2cbb', '\u2cbb'),
- ('\u2cbd', '\u2cbd'), ('\u2cbf', '\u2cbf'),
- ('\u2cc1', '\u2cc1'), ('\u2cc3', '\u2cc3'),
- ('\u2cc5', '\u2cc5'), ('\u2cc7', '\u2cc7'),
- ('\u2cc9', '\u2cc9'), ('\u2ccb', '\u2ccb'),
- ('\u2ccd', '\u2ccd'), ('\u2ccf', '\u2ccf'),
- ('\u2cd1', '\u2cd1'), ('\u2cd3', '\u2cd3'),
- ('\u2cd5', '\u2cd5'), ('\u2cd7', '\u2cd7'),
- ('\u2cd9', '\u2cd9'), ('\u2cdb', '\u2cdb'),
- ('\u2cdd', '\u2cdd'), ('\u2cdf', '\u2cdf'),
- ('\u2ce1', '\u2ce1'), ('\u2ce3', '\u2ce4'),
- ('\u2cec', '\u2cec'), ('\u2cee', '\u2cee'),
- ('\u2cf3', '\u2cf3'), ('\u2d00', '\u2d25'),
- ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'),
- ('\ua641', '\ua641'), ('\ua643', '\ua643'),
- ('\ua645', '\ua645'), ('\ua647', '\ua647'),
- ('\ua649', '\ua649'), ('\ua64b', '\ua64b'),
- ('\ua64d', '\ua64d'), ('\ua64f', '\ua64f'),
- ('\ua651', '\ua651'), ('\ua653', '\ua653'),
- ('\ua655', '\ua655'), ('\ua657', '\ua657'),
- ('\ua659', '\ua659'), ('\ua65b', '\ua65b'),
- ('\ua65d', '\ua65d'), ('\ua65f', '\ua65f'),
- ('\ua661', '\ua661'), ('\ua663', '\ua663'),
- ('\ua665', '\ua665'), ('\ua667', '\ua667'),
- ('\ua669', '\ua669'), ('\ua66b', '\ua66b'),
- ('\ua66d', '\ua66d'), ('\ua681', '\ua681'),
- ('\ua683', '\ua683'), ('\ua685', '\ua685'),
- ('\ua687', '\ua687'), ('\ua689', '\ua689'),
- ('\ua68b', '\ua68b'), ('\ua68d', '\ua68d'),
- ('\ua68f', '\ua68f'), ('\ua691', '\ua691'),
- ('\ua693', '\ua693'), ('\ua695', '\ua695'),
- ('\ua697', '\ua697'), ('\ua723', '\ua723'),
- ('\ua725', '\ua725'), ('\ua727', '\ua727'),
- ('\ua729', '\ua729'), ('\ua72b', '\ua72b'),
- ('\ua72d', '\ua72d'), ('\ua72f', '\ua731'),
- ('\ua733', '\ua733'), ('\ua735', '\ua735'),
- ('\ua737', '\ua737'), ('\ua739', '\ua739'),
- ('\ua73b', '\ua73b'), ('\ua73d', '\ua73d'),
- ('\ua73f', '\ua73f'), ('\ua741', '\ua741'),
- ('\ua743', '\ua743'), ('\ua745', '\ua745'),
- ('\ua747', '\ua747'), ('\ua749', '\ua749'),
- ('\ua74b', '\ua74b'), ('\ua74d', '\ua74d'),
- ('\ua74f', '\ua74f'), ('\ua751', '\ua751'),
- ('\ua753', '\ua753'), ('\ua755', '\ua755'),
- ('\ua757', '\ua757'), ('\ua759', '\ua759'),
- ('\ua75b', '\ua75b'), ('\ua75d', '\ua75d'),
- ('\ua75f', '\ua75f'), ('\ua761', '\ua761'),
- ('\ua763', '\ua763'), ('\ua765', '\ua765'),
- ('\ua767', '\ua767'), ('\ua769', '\ua769'),
- ('\ua76b', '\ua76b'), ('\ua76d', '\ua76d'),
- ('\ua76f', '\ua76f'), ('\ua770', '\ua770'),
- ('\ua771', '\ua778'), ('\ua77a', '\ua77a'),
- ('\ua77c', '\ua77c'), ('\ua77f', '\ua77f'),
- ('\ua781', '\ua781'), ('\ua783', '\ua783'),
- ('\ua785', '\ua785'), ('\ua787', '\ua787'),
- ('\ua78c', '\ua78c'), ('\ua78e', '\ua78e'),
- ('\ua791', '\ua791'), ('\ua793', '\ua793'),
- ('\ua7a1', '\ua7a1'), ('\ua7a3', '\ua7a3'),
- ('\ua7a5', '\ua7a5'), ('\ua7a7', '\ua7a7'),
- ('\ua7a9', '\ua7a9'), ('\ua7f8', '\ua7f9'),
- ('\ua7fa', '\ua7fa'), ('\ufb00', '\ufb06'),
- ('\ufb13', '\ufb17'), ('\uff41', '\uff5a'),
- ('\U00010428', '\U0001044f'), ('\U0001d41a', '\U0001d433'),
- ('\U0001d44e', '\U0001d454'), ('\U0001d456', '\U0001d467'),
- ('\U0001d482', '\U0001d49b'), ('\U0001d4b6', '\U0001d4b9'),
- ('\U0001d4bb', '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'),
- ('\U0001d4c5', '\U0001d4cf'), ('\U0001d4ea', '\U0001d503'),
- ('\U0001d51e', '\U0001d537'), ('\U0001d552', '\U0001d56b'),
- ('\U0001d586', '\U0001d59f'), ('\U0001d5ba', '\U0001d5d3'),
- ('\U0001d5ee', '\U0001d607'), ('\U0001d622', '\U0001d63b'),
- ('\U0001d656', '\U0001d66f'), ('\U0001d68a', '\U0001d6a5'),
- ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6e1'),
- ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d71b'),
- ('\U0001d736', '\U0001d74e'), ('\U0001d750', '\U0001d755'),
- ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d78f'),
- ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7c9'),
- ('\U0001d7cb', '\U0001d7cb')
- ];
-
- pub fn Lowercase(c: char) -> bool {
- super::bsearch_range_table(c, Lowercase_table)
- }
-
- static Uppercase_table : &'static [(char,char)] = &[
- ('\x41', '\x5a'), ('\xc0', '\xd6'),
- ('\xd8', '\xde'), ('\u0100', '\u0100'),
- ('\u0102', '\u0102'), ('\u0104', '\u0104'),
- ('\u0106', '\u0106'), ('\u0108', '\u0108'),
- ('\u010a', '\u010a'), ('\u010c', '\u010c'),
- ('\u010e', '\u010e'), ('\u0110', '\u0110'),
- ('\u0112', '\u0112'), ('\u0114', '\u0114'),
- ('\u0116', '\u0116'), ('\u0118', '\u0118'),
- ('\u011a', '\u011a'), ('\u011c', '\u011c'),
- ('\u011e', '\u011e'), ('\u0120', '\u0120'),
- ('\u0122', '\u0122'), ('\u0124', '\u0124'),
- ('\u0126', '\u0126'), ('\u0128', '\u0128'),
- ('\u012a', '\u012a'), ('\u012c', '\u012c'),
- ('\u012e', '\u012e'), ('\u0130', '\u0130'),
- ('\u0132', '\u0132'), ('\u0134', '\u0134'),
- ('\u0136', '\u0136'), ('\u0139', '\u0139'),
- ('\u013b', '\u013b'), ('\u013d', '\u013d'),
- ('\u013f', '\u013f'), ('\u0141', '\u0141'),
- ('\u0143', '\u0143'), ('\u0145', '\u0145'),
- ('\u0147', '\u0147'), ('\u014a', '\u014a'),
- ('\u014c', '\u014c'), ('\u014e', '\u014e'),
- ('\u0150', '\u0150'), ('\u0152', '\u0152'),
- ('\u0154', '\u0154'), ('\u0156', '\u0156'),
- ('\u0158', '\u0158'), ('\u015a', '\u015a'),
- ('\u015c', '\u015c'), ('\u015e', '\u015e'),
- ('\u0160', '\u0160'), ('\u0162', '\u0162'),
- ('\u0164', '\u0164'), ('\u0166', '\u0166'),
- ('\u0168', '\u0168'), ('\u016a', '\u016a'),
- ('\u016c', '\u016c'), ('\u016e', '\u016e'),
- ('\u0170', '\u0170'), ('\u0172', '\u0172'),
- ('\u0174', '\u0174'), ('\u0176', '\u0176'),
- ('\u0178', '\u0179'), ('\u017b', '\u017b'),
- ('\u017d', '\u017d'), ('\u0181', '\u0182'),
- ('\u0184', '\u0184'), ('\u0186', '\u0187'),
- ('\u0189', '\u018b'), ('\u018e', '\u0191'),
- ('\u0193', '\u0194'), ('\u0196', '\u0198'),
- ('\u019c', '\u019d'), ('\u019f', '\u01a0'),
- ('\u01a2', '\u01a2'), ('\u01a4', '\u01a4'),
- ('\u01a6', '\u01a7'), ('\u01a9', '\u01a9'),
- ('\u01ac', '\u01ac'), ('\u01ae', '\u01af'),
- ('\u01b1', '\u01b3'), ('\u01b5', '\u01b5'),
- ('\u01b7', '\u01b8'), ('\u01bc', '\u01bc'),
- ('\u01c4', '\u01c4'), ('\u01c7', '\u01c7'),
- ('\u01ca', '\u01ca'), ('\u01cd', '\u01cd'),
- ('\u01cf', '\u01cf'), ('\u01d1', '\u01d1'),
- ('\u01d3', '\u01d3'), ('\u01d5', '\u01d5'),
- ('\u01d7', '\u01d7'), ('\u01d9', '\u01d9'),
- ('\u01db', '\u01db'), ('\u01de', '\u01de'),
- ('\u01e0', '\u01e0'), ('\u01e2', '\u01e2'),
- ('\u01e4', '\u01e4'), ('\u01e6', '\u01e6'),
- ('\u01e8', '\u01e8'), ('\u01ea', '\u01ea'),
- ('\u01ec', '\u01ec'), ('\u01ee', '\u01ee'),
- ('\u01f1', '\u01f1'), ('\u01f4', '\u01f4'),
- ('\u01f6', '\u01f8'), ('\u01fa', '\u01fa'),
- ('\u01fc', '\u01fc'), ('\u01fe', '\u01fe'),
- ('\u0200', '\u0200'), ('\u0202', '\u0202'),
- ('\u0204', '\u0204'), ('\u0206', '\u0206'),
- ('\u0208', '\u0208'), ('\u020a', '\u020a'),
- ('\u020c', '\u020c'), ('\u020e', '\u020e'),
- ('\u0210', '\u0210'), ('\u0212', '\u0212'),
- ('\u0214', '\u0214'), ('\u0216', '\u0216'),
- ('\u0218', '\u0218'), ('\u021a', '\u021a'),
- ('\u021c', '\u021c'), ('\u021e', '\u021e'),
- ('\u0220', '\u0220'), ('\u0222', '\u0222'),
- ('\u0224', '\u0224'), ('\u0226', '\u0226'),
- ('\u0228', '\u0228'), ('\u022a', '\u022a'),
- ('\u022c', '\u022c'), ('\u022e', '\u022e'),
- ('\u0230', '\u0230'), ('\u0232', '\u0232'),
- ('\u023a', '\u023b'), ('\u023d', '\u023e'),
- ('\u0241', '\u0241'), ('\u0243', '\u0246'),
- ('\u0248', '\u0248'), ('\u024a', '\u024a'),
- ('\u024c', '\u024c'), ('\u024e', '\u024e'),
- ('\u0370', '\u0370'), ('\u0372', '\u0372'),
- ('\u0376', '\u0376'), ('\u0386', '\u0386'),
- ('\u0388', '\u038a'), ('\u038c', '\u038c'),
- ('\u038e', '\u038f'), ('\u0391', '\u03a1'),
- ('\u03a3', '\u03ab'), ('\u03cf', '\u03cf'),
- ('\u03d2', '\u03d4'), ('\u03d8', '\u03d8'),
- ('\u03da', '\u03da'), ('\u03dc', '\u03dc'),
- ('\u03de', '\u03de'), ('\u03e0', '\u03e0'),
- ('\u03e2', '\u03e2'), ('\u03e4', '\u03e4'),
- ('\u03e6', '\u03e6'), ('\u03e8', '\u03e8'),
- ('\u03ea', '\u03ea'), ('\u03ec', '\u03ec'),
- ('\u03ee', '\u03ee'), ('\u03f4', '\u03f4'),
- ('\u03f7', '\u03f7'), ('\u03f9', '\u03fa'),
- ('\u03fd', '\u042f'), ('\u0460', '\u0460'),
- ('\u0462', '\u0462'), ('\u0464', '\u0464'),
- ('\u0466', '\u0466'), ('\u0468', '\u0468'),
- ('\u046a', '\u046a'), ('\u046c', '\u046c'),
- ('\u046e', '\u046e'), ('\u0470', '\u0470'),
- ('\u0472', '\u0472'), ('\u0474', '\u0474'),
- ('\u0476', '\u0476'), ('\u0478', '\u0478'),
- ('\u047a', '\u047a'), ('\u047c', '\u047c'),
- ('\u047e', '\u047e'), ('\u0480', '\u0480'),
- ('\u048a', '\u048a'), ('\u048c', '\u048c'),
- ('\u048e', '\u048e'), ('\u0490', '\u0490'),
- ('\u0492', '\u0492'), ('\u0494', '\u0494'),
- ('\u0496', '\u0496'), ('\u0498', '\u0498'),
- ('\u049a', '\u049a'), ('\u049c', '\u049c'),
- ('\u049e', '\u049e'), ('\u04a0', '\u04a0'),
- ('\u04a2', '\u04a2'), ('\u04a4', '\u04a4'),
- ('\u04a6', '\u04a6'), ('\u04a8', '\u04a8'),
- ('\u04aa', '\u04aa'), ('\u04ac', '\u04ac'),
- ('\u04ae', '\u04ae'), ('\u04b0', '\u04b0'),
- ('\u04b2', '\u04b2'), ('\u04b4', '\u04b4'),
- ('\u04b6', '\u04b6'), ('\u04b8', '\u04b8'),
- ('\u04ba', '\u04ba'), ('\u04bc', '\u04bc'),
- ('\u04be', '\u04be'), ('\u04c0', '\u04c1'),
- ('\u04c3', '\u04c3'), ('\u04c5', '\u04c5'),
- ('\u04c7', '\u04c7'), ('\u04c9', '\u04c9'),
- ('\u04cb', '\u04cb'), ('\u04cd', '\u04cd'),
- ('\u04d0', '\u04d0'), ('\u04d2', '\u04d2'),
- ('\u04d4', '\u04d4'), ('\u04d6', '\u04d6'),
- ('\u04d8', '\u04d8'), ('\u04da', '\u04da'),
- ('\u04dc', '\u04dc'), ('\u04de', '\u04de'),
- ('\u04e0', '\u04e0'), ('\u04e2', '\u04e2'),
- ('\u04e4', '\u04e4'), ('\u04e6', '\u04e6'),
- ('\u04e8', '\u04e8'), ('\u04ea', '\u04ea'),
- ('\u04ec', '\u04ec'), ('\u04ee', '\u04ee'),
- ('\u04f0', '\u04f0'), ('\u04f2', '\u04f2'),
- ('\u04f4', '\u04f4'), ('\u04f6', '\u04f6'),
- ('\u04f8', '\u04f8'), ('\u04fa', '\u04fa'),
- ('\u04fc', '\u04fc'), ('\u04fe', '\u04fe'),
- ('\u0500', '\u0500'), ('\u0502', '\u0502'),
- ('\u0504', '\u0504'), ('\u0506', '\u0506'),
- ('\u0508', '\u0508'), ('\u050a', '\u050a'),
- ('\u050c', '\u050c'), ('\u050e', '\u050e'),
- ('\u0510', '\u0510'), ('\u0512', '\u0512'),
- ('\u0514', '\u0514'), ('\u0516', '\u0516'),
- ('\u0518', '\u0518'), ('\u051a', '\u051a'),
- ('\u051c', '\u051c'), ('\u051e', '\u051e'),
- ('\u0520', '\u0520'), ('\u0522', '\u0522'),
- ('\u0524', '\u0524'), ('\u0526', '\u0526'),
- ('\u0531', '\u0556'), ('\u10a0', '\u10c5'),
- ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'),
- ('\u1e00', '\u1e00'), ('\u1e02', '\u1e02'),
- ('\u1e04', '\u1e04'), ('\u1e06', '\u1e06'),
- ('\u1e08', '\u1e08'), ('\u1e0a', '\u1e0a'),
- ('\u1e0c', '\u1e0c'), ('\u1e0e', '\u1e0e'),
- ('\u1e10', '\u1e10'), ('\u1e12', '\u1e12'),
- ('\u1e14', '\u1e14'), ('\u1e16', '\u1e16'),
- ('\u1e18', '\u1e18'), ('\u1e1a', '\u1e1a'),
- ('\u1e1c', '\u1e1c'), ('\u1e1e', '\u1e1e'),
- ('\u1e20', '\u1e20'), ('\u1e22', '\u1e22'),
- ('\u1e24', '\u1e24'), ('\u1e26', '\u1e26'),
- ('\u1e28', '\u1e28'), ('\u1e2a', '\u1e2a'),
- ('\u1e2c', '\u1e2c'), ('\u1e2e', '\u1e2e'),
- ('\u1e30', '\u1e30'), ('\u1e32', '\u1e32'),
- ('\u1e34', '\u1e34'), ('\u1e36', '\u1e36'),
- ('\u1e38', '\u1e38'), ('\u1e3a', '\u1e3a'),
- ('\u1e3c', '\u1e3c'), ('\u1e3e', '\u1e3e'),
- ('\u1e40', '\u1e40'), ('\u1e42', '\u1e42'),
- ('\u1e44', '\u1e44'), ('\u1e46', '\u1e46'),
- ('\u1e48', '\u1e48'), ('\u1e4a', '\u1e4a'),
- ('\u1e4c', '\u1e4c'), ('\u1e4e', '\u1e4e'),
- ('\u1e50', '\u1e50'), ('\u1e52', '\u1e52'),
- ('\u1e54', '\u1e54'), ('\u1e56', '\u1e56'),
- ('\u1e58', '\u1e58'), ('\u1e5a', '\u1e5a'),
- ('\u1e5c', '\u1e5c'), ('\u1e5e', '\u1e5e'),
- ('\u1e60', '\u1e60'), ('\u1e62', '\u1e62'),
- ('\u1e64', '\u1e64'), ('\u1e66', '\u1e66'),
- ('\u1e68', '\u1e68'), ('\u1e6a', '\u1e6a'),
- ('\u1e6c', '\u1e6c'), ('\u1e6e', '\u1e6e'),
- ('\u1e70', '\u1e70'), ('\u1e72', '\u1e72'),
- ('\u1e74', '\u1e74'), ('\u1e76', '\u1e76'),
- ('\u1e78', '\u1e78'), ('\u1e7a', '\u1e7a'),
- ('\u1e7c', '\u1e7c'), ('\u1e7e', '\u1e7e'),
- ('\u1e80', '\u1e80'), ('\u1e82', '\u1e82'),
- ('\u1e84', '\u1e84'), ('\u1e86', '\u1e86'),
- ('\u1e88', '\u1e88'), ('\u1e8a', '\u1e8a'),
- ('\u1e8c', '\u1e8c'), ('\u1e8e', '\u1e8e'),
- ('\u1e90', '\u1e90'), ('\u1e92', '\u1e92'),
- ('\u1e94', '\u1e94'), ('\u1e9e', '\u1e9e'),
- ('\u1ea0', '\u1ea0'), ('\u1ea2', '\u1ea2'),
- ('\u1ea4', '\u1ea4'), ('\u1ea6', '\u1ea6'),
- ('\u1ea8', '\u1ea8'), ('\u1eaa', '\u1eaa'),
- ('\u1eac', '\u1eac'), ('\u1eae', '\u1eae'),
- ('\u1eb0', '\u1eb0'), ('\u1eb2', '\u1eb2'),
- ('\u1eb4', '\u1eb4'), ('\u1eb6', '\u1eb6'),
- ('\u1eb8', '\u1eb8'), ('\u1eba', '\u1eba'),
- ('\u1ebc', '\u1ebc'), ('\u1ebe', '\u1ebe'),
- ('\u1ec0', '\u1ec0'), ('\u1ec2', '\u1ec2'),
- ('\u1ec4', '\u1ec4'), ('\u1ec6', '\u1ec6'),
- ('\u1ec8', '\u1ec8'), ('\u1eca', '\u1eca'),
- ('\u1ecc', '\u1ecc'), ('\u1ece', '\u1ece'),
- ('\u1ed0', '\u1ed0'), ('\u1ed2', '\u1ed2'),
- ('\u1ed4', '\u1ed4'), ('\u1ed6', '\u1ed6'),
- ('\u1ed8', '\u1ed8'), ('\u1eda', '\u1eda'),
- ('\u1edc', '\u1edc'), ('\u1ede', '\u1ede'),
- ('\u1ee0', '\u1ee0'), ('\u1ee2', '\u1ee2'),
- ('\u1ee4', '\u1ee4'), ('\u1ee6', '\u1ee6'),
- ('\u1ee8', '\u1ee8'), ('\u1eea', '\u1eea'),
- ('\u1eec', '\u1eec'), ('\u1eee', '\u1eee'),
- ('\u1ef0', '\u1ef0'), ('\u1ef2', '\u1ef2'),
- ('\u1ef4', '\u1ef4'), ('\u1ef6', '\u1ef6'),
- ('\u1ef8', '\u1ef8'), ('\u1efa', '\u1efa'),
- ('\u1efc', '\u1efc'), ('\u1efe', '\u1efe'),
- ('\u1f08', '\u1f0f'), ('\u1f18', '\u1f1d'),
- ('\u1f28', '\u1f2f'), ('\u1f38', '\u1f3f'),
- ('\u1f48', '\u1f4d'), ('\u1f59', '\u1f59'),
- ('\u1f5b', '\u1f5b'), ('\u1f5d', '\u1f5d'),
- ('\u1f5f', '\u1f5f'), ('\u1f68', '\u1f6f'),
- ('\u1fb8', '\u1fbb'), ('\u1fc8', '\u1fcb'),
- ('\u1fd8', '\u1fdb'), ('\u1fe8', '\u1fec'),
- ('\u1ff8', '\u1ffb'), ('\u2102', '\u2102'),
- ('\u2107', '\u2107'), ('\u210b', '\u210d'),
- ('\u2110', '\u2112'), ('\u2115', '\u2115'),
- ('\u2119', '\u211d'), ('\u2124', '\u2124'),
- ('\u2126', '\u2126'), ('\u2128', '\u2128'),
- ('\u212a', '\u212d'), ('\u2130', '\u2133'),
- ('\u213e', '\u213f'), ('\u2145', '\u2145'),
- ('\u2160', '\u216f'), ('\u2183', '\u2183'),
- ('\u24b6', '\u24cf'), ('\u2c00', '\u2c2e'),
- ('\u2c60', '\u2c60'), ('\u2c62', '\u2c64'),
- ('\u2c67', '\u2c67'), ('\u2c69', '\u2c69'),
- ('\u2c6b', '\u2c6b'), ('\u2c6d', '\u2c70'),
- ('\u2c72', '\u2c72'), ('\u2c75', '\u2c75'),
- ('\u2c7e', '\u2c80'), ('\u2c82', '\u2c82'),
- ('\u2c84', '\u2c84'), ('\u2c86', '\u2c86'),
- ('\u2c88', '\u2c88'), ('\u2c8a', '\u2c8a'),
- ('\u2c8c', '\u2c8c'), ('\u2c8e', '\u2c8e'),
- ('\u2c90', '\u2c90'), ('\u2c92', '\u2c92'),
- ('\u2c94', '\u2c94'), ('\u2c96', '\u2c96'),
- ('\u2c98', '\u2c98'), ('\u2c9a', '\u2c9a'),
- ('\u2c9c', '\u2c9c'), ('\u2c9e', '\u2c9e'),
- ('\u2ca0', '\u2ca0'), ('\u2ca2', '\u2ca2'),
- ('\u2ca4', '\u2ca4'), ('\u2ca6', '\u2ca6'),
- ('\u2ca8', '\u2ca8'), ('\u2caa', '\u2caa'),
- ('\u2cac', '\u2cac'), ('\u2cae', '\u2cae'),
- ('\u2cb0', '\u2cb0'), ('\u2cb2', '\u2cb2'),
- ('\u2cb4', '\u2cb4'), ('\u2cb6', '\u2cb6'),
- ('\u2cb8', '\u2cb8'), ('\u2cba', '\u2cba'),
- ('\u2cbc', '\u2cbc'), ('\u2cbe', '\u2cbe'),
- ('\u2cc0', '\u2cc0'), ('\u2cc2', '\u2cc2'),
- ('\u2cc4', '\u2cc4'), ('\u2cc6', '\u2cc6'),
- ('\u2cc8', '\u2cc8'), ('\u2cca', '\u2cca'),
- ('\u2ccc', '\u2ccc'), ('\u2cce', '\u2cce'),
- ('\u2cd0', '\u2cd0'), ('\u2cd2', '\u2cd2'),
- ('\u2cd4', '\u2cd4'), ('\u2cd6', '\u2cd6'),
- ('\u2cd8', '\u2cd8'), ('\u2cda', '\u2cda'),
- ('\u2cdc', '\u2cdc'), ('\u2cde', '\u2cde'),
- ('\u2ce0', '\u2ce0'), ('\u2ce2', '\u2ce2'),
- ('\u2ceb', '\u2ceb'), ('\u2ced', '\u2ced'),
- ('\u2cf2', '\u2cf2'), ('\ua640', '\ua640'),
- ('\ua642', '\ua642'), ('\ua644', '\ua644'),
- ('\ua646', '\ua646'), ('\ua648', '\ua648'),
- ('\ua64a', '\ua64a'), ('\ua64c', '\ua64c'),
- ('\ua64e', '\ua64e'), ('\ua650', '\ua650'),
- ('\ua652', '\ua652'), ('\ua654', '\ua654'),
- ('\ua656', '\ua656'), ('\ua658', '\ua658'),
- ('\ua65a', '\ua65a'), ('\ua65c', '\ua65c'),
- ('\ua65e', '\ua65e'), ('\ua660', '\ua660'),
- ('\ua662', '\ua662'), ('\ua664', '\ua664'),
- ('\ua666', '\ua666'), ('\ua668', '\ua668'),
- ('\ua66a', '\ua66a'), ('\ua66c', '\ua66c'),
- ('\ua680', '\ua680'), ('\ua682', '\ua682'),
- ('\ua684', '\ua684'), ('\ua686', '\ua686'),
- ('\ua688', '\ua688'), ('\ua68a', '\ua68a'),
- ('\ua68c', '\ua68c'), ('\ua68e', '\ua68e'),
- ('\ua690', '\ua690'), ('\ua692', '\ua692'),
- ('\ua694', '\ua694'), ('\ua696', '\ua696'),
- ('\ua722', '\ua722'), ('\ua724', '\ua724'),
- ('\ua726', '\ua726'), ('\ua728', '\ua728'),
- ('\ua72a', '\ua72a'), ('\ua72c', '\ua72c'),
- ('\ua72e', '\ua72e'), ('\ua732', '\ua732'),
- ('\ua734', '\ua734'), ('\ua736', '\ua736'),
- ('\ua738', '\ua738'), ('\ua73a', '\ua73a'),
- ('\ua73c', '\ua73c'), ('\ua73e', '\ua73e'),
- ('\ua740', '\ua740'), ('\ua742', '\ua742'),
- ('\ua744', '\ua744'), ('\ua746', '\ua746'),
- ('\ua748', '\ua748'), ('\ua74a', '\ua74a'),
- ('\ua74c', '\ua74c'), ('\ua74e', '\ua74e'),
- ('\ua750', '\ua750'), ('\ua752', '\ua752'),
- ('\ua754', '\ua754'), ('\ua756', '\ua756'),
- ('\ua758', '\ua758'), ('\ua75a', '\ua75a'),
- ('\ua75c', '\ua75c'), ('\ua75e', '\ua75e'),
- ('\ua760', '\ua760'), ('\ua762', '\ua762'),
- ('\ua764', '\ua764'), ('\ua766', '\ua766'),
- ('\ua768', '\ua768'), ('\ua76a', '\ua76a'),
- ('\ua76c', '\ua76c'), ('\ua76e', '\ua76e'),
- ('\ua779', '\ua779'), ('\ua77b', '\ua77b'),
- ('\ua77d', '\ua77e'), ('\ua780', '\ua780'),
- ('\ua782', '\ua782'), ('\ua784', '\ua784'),
- ('\ua786', '\ua786'), ('\ua78b', '\ua78b'),
- ('\ua78d', '\ua78d'), ('\ua790', '\ua790'),
- ('\ua792', '\ua792'), ('\ua7a0', '\ua7a0'),
- ('\ua7a2', '\ua7a2'), ('\ua7a4', '\ua7a4'),
- ('\ua7a6', '\ua7a6'), ('\ua7a8', '\ua7a8'),
- ('\ua7aa', '\ua7aa'), ('\uff21', '\uff3a'),
- ('\U00010400', '\U00010427'), ('\U0001d400', '\U0001d419'),
- ('\U0001d434', '\U0001d44d'), ('\U0001d468', '\U0001d481'),
- ('\U0001d49c', '\U0001d49c'), ('\U0001d49e', '\U0001d49f'),
- ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5', '\U0001d4a6'),
- ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b5'),
- ('\U0001d4d0', '\U0001d4e9'), ('\U0001d504', '\U0001d505'),
- ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'),
- ('\U0001d516', '\U0001d51c'), ('\U0001d538', '\U0001d539'),
- ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'),
- ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'),
- ('\U0001d56c', '\U0001d585'), ('\U0001d5a0', '\U0001d5b9'),
- ('\U0001d5d4', '\U0001d5ed'), ('\U0001d608', '\U0001d621'),
- ('\U0001d63c', '\U0001d655'), ('\U0001d670', '\U0001d689'),
- ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6e2', '\U0001d6fa'),
- ('\U0001d71c', '\U0001d734'), ('\U0001d756', '\U0001d76e'),
- ('\U0001d790', '\U0001d7a8'), ('\U0001d7ca', '\U0001d7ca')
- ];
-
- pub fn Uppercase(c: char) -> bool {
- super::bsearch_range_table(c, Uppercase_table)
- }
-
- static XID_Continue_table : &'static [(char,char)] = &[
- ('\x30', '\x39'), ('\x41', '\x5a'),
- ('\x5f', '\x5f'), ('\x61', '\x7a'),
- ('\xaa', '\xaa'), ('\xb5', '\xb5'),
- ('\xb7', '\xb7'), ('\xba', '\xba'),
- ('\xc0', '\xd6'), ('\xd8', '\xf6'),
- ('\xf8', '\u01ba'), ('\u01bb', '\u01bb'),
- ('\u01bc', '\u01bf'), ('\u01c0', '\u01c3'),
- ('\u01c4', '\u0293'), ('\u0294', '\u0294'),
- ('\u0295', '\u02af'), ('\u02b0', '\u02c1'),
- ('\u02c6', '\u02d1'), ('\u02e0', '\u02e4'),
- ('\u02ec', '\u02ec'), ('\u02ee', '\u02ee'),
- ('\u0300', '\u036f'), ('\u0370', '\u0373'),
- ('\u0374', '\u0374'), ('\u0376', '\u0377'),
- ('\u037b', '\u037d'), ('\u0386', '\u0386'),
- ('\u0387', '\u0387'), ('\u0388', '\u038a'),
- ('\u038c', '\u038c'), ('\u038e', '\u03a1'),
- ('\u03a3', '\u03f5'), ('\u03f7', '\u0481'),
- ('\u0483', '\u0487'), ('\u048a', '\u0527'),
- ('\u0531', '\u0556'), ('\u0559', '\u0559'),
- ('\u0561', '\u0587'), ('\u0591', '\u05bd'),
- ('\u05bf', '\u05bf'), ('\u05c1', '\u05c2'),
- ('\u05c4', '\u05c5'), ('\u05c7', '\u05c7'),
- ('\u05d0', '\u05ea'), ('\u05f0', '\u05f2'),
- ('\u0610', '\u061a'), ('\u0620', '\u063f'),
- ('\u0640', '\u0640'), ('\u0641', '\u064a'),
- ('\u064b', '\u065f'), ('\u0660', '\u0669'),
- ('\u066e', '\u066f'), ('\u0670', '\u0670'),
- ('\u0671', '\u06d3'), ('\u06d5', '\u06d5'),
- ('\u06d6', '\u06dc'), ('\u06df', '\u06e4'),
- ('\u06e5', '\u06e6'), ('\u06e7', '\u06e8'),
- ('\u06ea', '\u06ed'), ('\u06ee', '\u06ef'),
- ('\u06f0', '\u06f9'), ('\u06fa', '\u06fc'),
- ('\u06ff', '\u06ff'), ('\u0710', '\u0710'),
- ('\u0711', '\u0711'), ('\u0712', '\u072f'),
- ('\u0730', '\u074a'), ('\u074d', '\u07a5'),
- ('\u07a6', '\u07b0'), ('\u07b1', '\u07b1'),
- ('\u07c0', '\u07c9'), ('\u07ca', '\u07ea'),
- ('\u07eb', '\u07f3'), ('\u07f4', '\u07f5'),
- ('\u07fa', '\u07fa'), ('\u0800', '\u0815'),
- ('\u0816', '\u0819'), ('\u081a', '\u081a'),
- ('\u081b', '\u0823'), ('\u0824', '\u0824'),
- ('\u0825', '\u0827'), ('\u0828', '\u0828'),
- ('\u0829', '\u082d'), ('\u0840', '\u0858'),
- ('\u0859', '\u085b'), ('\u08a0', '\u08a0'),
- ('\u08a2', '\u08ac'), ('\u08e4', '\u08fe'),
- ('\u0900', '\u0902'), ('\u0903', '\u0903'),
- ('\u0904', '\u0939'), ('\u093a', '\u093a'),
- ('\u093b', '\u093b'), ('\u093c', '\u093c'),
- ('\u093d', '\u093d'), ('\u093e', '\u0940'),
- ('\u0941', '\u0948'), ('\u0949', '\u094c'),
- ('\u094d', '\u094d'), ('\u094e', '\u094f'),
- ('\u0950', '\u0950'), ('\u0951', '\u0957'),
- ('\u0958', '\u0961'), ('\u0962', '\u0963'),
- ('\u0966', '\u096f'), ('\u0971', '\u0971'),
- ('\u0972', '\u0977'), ('\u0979', '\u097f'),
- ('\u0981', '\u0981'), ('\u0982', '\u0983'),
- ('\u0985', '\u098c'), ('\u098f', '\u0990'),
- ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'),
- ('\u09b2', '\u09b2'), ('\u09b6', '\u09b9'),
- ('\u09bc', '\u09bc'), ('\u09bd', '\u09bd'),
- ('\u09be', '\u09c0'), ('\u09c1', '\u09c4'),
- ('\u09c7', '\u09c8'), ('\u09cb', '\u09cc'),
- ('\u09cd', '\u09cd'), ('\u09ce', '\u09ce'),
- ('\u09d7', '\u09d7'), ('\u09dc', '\u09dd'),
- ('\u09df', '\u09e1'), ('\u09e2', '\u09e3'),
- ('\u09e6', '\u09ef'), ('\u09f0', '\u09f1'),
- ('\u0a01', '\u0a02'), ('\u0a03', '\u0a03'),
- ('\u0a05', '\u0a0a'), ('\u0a0f', '\u0a10'),
- ('\u0a13', '\u0a28'), ('\u0a2a', '\u0a30'),
- ('\u0a32', '\u0a33'), ('\u0a35', '\u0a36'),
- ('\u0a38', '\u0a39'), ('\u0a3c', '\u0a3c'),
- ('\u0a3e', '\u0a40'), ('\u0a41', '\u0a42'),
- ('\u0a47', '\u0a48'), ('\u0a4b', '\u0a4d'),
- ('\u0a51', '\u0a51'), ('\u0a59', '\u0a5c'),
- ('\u0a5e', '\u0a5e'), ('\u0a66', '\u0a6f'),
- ('\u0a70', '\u0a71'), ('\u0a72', '\u0a74'),
- ('\u0a75', '\u0a75'), ('\u0a81', '\u0a82'),
- ('\u0a83', '\u0a83'), ('\u0a85', '\u0a8d'),
- ('\u0a8f', '\u0a91'), ('\u0a93', '\u0aa8'),
- ('\u0aaa', '\u0ab0'), ('\u0ab2', '\u0ab3'),
- ('\u0ab5', '\u0ab9'), ('\u0abc', '\u0abc'),
- ('\u0abd', '\u0abd'), ('\u0abe', '\u0ac0'),
- ('\u0ac1', '\u0ac5'), ('\u0ac7', '\u0ac8'),
- ('\u0ac9', '\u0ac9'), ('\u0acb', '\u0acc'),
- ('\u0acd', '\u0acd'), ('\u0ad0', '\u0ad0'),
- ('\u0ae0', '\u0ae1'), ('\u0ae2', '\u0ae3'),
- ('\u0ae6', '\u0aef'), ('\u0b01', '\u0b01'),
- ('\u0b02', '\u0b03'), ('\u0b05', '\u0b0c'),
- ('\u0b0f', '\u0b10'), ('\u0b13', '\u0b28'),
- ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'),
- ('\u0b35', '\u0b39'), ('\u0b3c', '\u0b3c'),
- ('\u0b3d', '\u0b3d'), ('\u0b3e', '\u0b3e'),
- ('\u0b3f', '\u0b3f'), ('\u0b40', '\u0b40'),
- ('\u0b41', '\u0b44'), ('\u0b47', '\u0b48'),
- ('\u0b4b', '\u0b4c'), ('\u0b4d', '\u0b4d'),
- ('\u0b56', '\u0b56'), ('\u0b57', '\u0b57'),
- ('\u0b5c', '\u0b5d'), ('\u0b5f', '\u0b61'),
- ('\u0b62', '\u0b63'), ('\u0b66', '\u0b6f'),
- ('\u0b71', '\u0b71'), ('\u0b82', '\u0b82'),
- ('\u0b83', '\u0b83'), ('\u0b85', '\u0b8a'),
- ('\u0b8e', '\u0b90'), ('\u0b92', '\u0b95'),
- ('\u0b99', '\u0b9a'), ('\u0b9c', '\u0b9c'),
- ('\u0b9e', '\u0b9f'), ('\u0ba3', '\u0ba4'),
- ('\u0ba8', '\u0baa'), ('\u0bae', '\u0bb9'),
- ('\u0bbe', '\u0bbf'), ('\u0bc0', '\u0bc0'),
- ('\u0bc1', '\u0bc2'), ('\u0bc6', '\u0bc8'),
- ('\u0bca', '\u0bcc'), ('\u0bcd', '\u0bcd'),
- ('\u0bd0', '\u0bd0'), ('\u0bd7', '\u0bd7'),
- ('\u0be6', '\u0bef'), ('\u0c01', '\u0c03'),
- ('\u0c05', '\u0c0c'), ('\u0c0e', '\u0c10'),
- ('\u0c12', '\u0c28'), ('\u0c2a', '\u0c33'),
- ('\u0c35', '\u0c39'), ('\u0c3d', '\u0c3d'),
- ('\u0c3e', '\u0c40'), ('\u0c41', '\u0c44'),
- ('\u0c46', '\u0c48'), ('\u0c4a', '\u0c4d'),
- ('\u0c55', '\u0c56'), ('\u0c58', '\u0c59'),
- ('\u0c60', '\u0c61'), ('\u0c62', '\u0c63'),
- ('\u0c66', '\u0c6f'), ('\u0c82', '\u0c83'),
- ('\u0c85', '\u0c8c'), ('\u0c8e', '\u0c90'),
- ('\u0c92', '\u0ca8'), ('\u0caa', '\u0cb3'),
- ('\u0cb5', '\u0cb9'), ('\u0cbc', '\u0cbc'),
- ('\u0cbd', '\u0cbd'), ('\u0cbe', '\u0cbe'),
- ('\u0cbf', '\u0cbf'), ('\u0cc0', '\u0cc4'),
- ('\u0cc6', '\u0cc6'), ('\u0cc7', '\u0cc8'),
- ('\u0cca', '\u0ccb'), ('\u0ccc', '\u0ccd'),
- ('\u0cd5', '\u0cd6'), ('\u0cde', '\u0cde'),
- ('\u0ce0', '\u0ce1'), ('\u0ce2', '\u0ce3'),
- ('\u0ce6', '\u0cef'), ('\u0cf1', '\u0cf2'),
- ('\u0d02', '\u0d03'), ('\u0d05', '\u0d0c'),
- ('\u0d0e', '\u0d10'), ('\u0d12', '\u0d3a'),
- ('\u0d3d', '\u0d3d'), ('\u0d3e', '\u0d40'),
- ('\u0d41', '\u0d44'), ('\u0d46', '\u0d48'),
- ('\u0d4a', '\u0d4c'), ('\u0d4d', '\u0d4d'),
- ('\u0d4e', '\u0d4e'), ('\u0d57', '\u0d57'),
- ('\u0d60', '\u0d61'), ('\u0d62', '\u0d63'),
- ('\u0d66', '\u0d6f'), ('\u0d7a', '\u0d7f'),
- ('\u0d82', '\u0d83'), ('\u0d85', '\u0d96'),
- ('\u0d9a', '\u0db1'), ('\u0db3', '\u0dbb'),
- ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'),
- ('\u0dca', '\u0dca'), ('\u0dcf', '\u0dd1'),
- ('\u0dd2', '\u0dd4'), ('\u0dd6', '\u0dd6'),
- ('\u0dd8', '\u0ddf'), ('\u0df2', '\u0df3'),
- ('\u0e01', '\u0e30'), ('\u0e31', '\u0e31'),
- ('\u0e32', '\u0e33'), ('\u0e34', '\u0e3a'),
- ('\u0e40', '\u0e45'), ('\u0e46', '\u0e46'),
- ('\u0e47', '\u0e4e'), ('\u0e50', '\u0e59'),
- ('\u0e81', '\u0e82'), ('\u0e84', '\u0e84'),
- ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'),
- ('\u0e8d', '\u0e8d'), ('\u0e94', '\u0e97'),
- ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'),
- ('\u0ea5', '\u0ea5'), ('\u0ea7', '\u0ea7'),
- ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'),
- ('\u0eb1', '\u0eb1'), ('\u0eb2', '\u0eb3'),
- ('\u0eb4', '\u0eb9'), ('\u0ebb', '\u0ebc'),
- ('\u0ebd', '\u0ebd'), ('\u0ec0', '\u0ec4'),
- ('\u0ec6', '\u0ec6'), ('\u0ec8', '\u0ecd'),
- ('\u0ed0', '\u0ed9'), ('\u0edc', '\u0edf'),
- ('\u0f00', '\u0f00'), ('\u0f18', '\u0f19'),
- ('\u0f20', '\u0f29'), ('\u0f35', '\u0f35'),
- ('\u0f37', '\u0f37'), ('\u0f39', '\u0f39'),
- ('\u0f3e', '\u0f3f'), ('\u0f40', '\u0f47'),
- ('\u0f49', '\u0f6c'), ('\u0f71', '\u0f7e'),
- ('\u0f7f', '\u0f7f'), ('\u0f80', '\u0f84'),
- ('\u0f86', '\u0f87'), ('\u0f88', '\u0f8c'),
- ('\u0f8d', '\u0f97'), ('\u0f99', '\u0fbc'),
- ('\u0fc6', '\u0fc6'), ('\u1000', '\u102a'),
- ('\u102b', '\u102c'), ('\u102d', '\u1030'),
- ('\u1031', '\u1031'), ('\u1032', '\u1037'),
- ('\u1038', '\u1038'), ('\u1039', '\u103a'),
- ('\u103b', '\u103c'), ('\u103d', '\u103e'),
- ('\u103f', '\u103f'), ('\u1040', '\u1049'),
- ('\u1050', '\u1055'), ('\u1056', '\u1057'),
- ('\u1058', '\u1059'), ('\u105a', '\u105d'),
- ('\u105e', '\u1060'), ('\u1061', '\u1061'),
- ('\u1062', '\u1064'), ('\u1065', '\u1066'),
- ('\u1067', '\u106d'), ('\u106e', '\u1070'),
- ('\u1071', '\u1074'), ('\u1075', '\u1081'),
- ('\u1082', '\u1082'), ('\u1083', '\u1084'),
- ('\u1085', '\u1086'), ('\u1087', '\u108c'),
- ('\u108d', '\u108d'), ('\u108e', '\u108e'),
- ('\u108f', '\u108f'), ('\u1090', '\u1099'),
- ('\u109a', '\u109c'), ('\u109d', '\u109d'),
- ('\u10a0', '\u10c5'), ('\u10c7', '\u10c7'),
- ('\u10cd', '\u10cd'), ('\u10d0', '\u10fa'),
- ('\u10fc', '\u10fc'), ('\u10fd', '\u1248'),
- ('\u124a', '\u124d'), ('\u1250', '\u1256'),
- ('\u1258', '\u1258'), ('\u125a', '\u125d'),
- ('\u1260', '\u1288'), ('\u128a', '\u128d'),
- ('\u1290', '\u12b0'), ('\u12b2', '\u12b5'),
- ('\u12b8', '\u12be'), ('\u12c0', '\u12c0'),
- ('\u12c2', '\u12c5'), ('\u12c8', '\u12d6'),
- ('\u12d8', '\u1310'), ('\u1312', '\u1315'),
- ('\u1318', '\u135a'), ('\u135d', '\u135f'),
- ('\u1369', '\u1371'), ('\u1380', '\u138f'),
- ('\u13a0', '\u13f4'), ('\u1401', '\u166c'),
- ('\u166f', '\u167f'), ('\u1681', '\u169a'),
- ('\u16a0', '\u16ea'), ('\u16ee', '\u16f0'),
- ('\u1700', '\u170c'), ('\u170e', '\u1711'),
- ('\u1712', '\u1714'), ('\u1720', '\u1731'),
- ('\u1732', '\u1734'), ('\u1740', '\u1751'),
- ('\u1752', '\u1753'), ('\u1760', '\u176c'),
- ('\u176e', '\u1770'), ('\u1772', '\u1773'),
- ('\u1780', '\u17b3'), ('\u17b4', '\u17b5'),
- ('\u17b6', '\u17b6'), ('\u17b7', '\u17bd'),
- ('\u17be', '\u17c5'), ('\u17c6', '\u17c6'),
- ('\u17c7', '\u17c8'), ('\u17c9', '\u17d3'),
- ('\u17d7', '\u17d7'), ('\u17dc', '\u17dc'),
- ('\u17dd', '\u17dd'), ('\u17e0', '\u17e9'),
- ('\u180b', '\u180d'), ('\u1810', '\u1819'),
- ('\u1820', '\u1842'), ('\u1843', '\u1843'),
- ('\u1844', '\u1877'), ('\u1880', '\u18a8'),
- ('\u18a9', '\u18a9'), ('\u18aa', '\u18aa'),
- ('\u18b0', '\u18f5'), ('\u1900', '\u191c'),
- ('\u1920', '\u1922'), ('\u1923', '\u1926'),
- ('\u1927', '\u1928'), ('\u1929', '\u192b'),
- ('\u1930', '\u1931'), ('\u1932', '\u1932'),
- ('\u1933', '\u1938'), ('\u1939', '\u193b'),
- ('\u1946', '\u194f'), ('\u1950', '\u196d'),
- ('\u1970', '\u1974'), ('\u1980', '\u19ab'),
- ('\u19b0', '\u19c0'), ('\u19c1', '\u19c7'),
- ('\u19c8', '\u19c9'), ('\u19d0', '\u19d9'),
- ('\u19da', '\u19da'), ('\u1a00', '\u1a16'),
- ('\u1a17', '\u1a18'), ('\u1a19', '\u1a1a'),
- ('\u1a1b', '\u1a1b'), ('\u1a20', '\u1a54'),
- ('\u1a55', '\u1a55'), ('\u1a56', '\u1a56'),
- ('\u1a57', '\u1a57'), ('\u1a58', '\u1a5e'),
- ('\u1a60', '\u1a60'), ('\u1a61', '\u1a61'),
- ('\u1a62', '\u1a62'), ('\u1a63', '\u1a64'),
- ('\u1a65', '\u1a6c'), ('\u1a6d', '\u1a72'),
- ('\u1a73', '\u1a7c'), ('\u1a7f', '\u1a7f'),
- ('\u1a80', '\u1a89'), ('\u1a90', '\u1a99'),
- ('\u1aa7', '\u1aa7'), ('\u1b00', '\u1b03'),
- ('\u1b04', '\u1b04'), ('\u1b05', '\u1b33'),
- ('\u1b34', '\u1b34'), ('\u1b35', '\u1b35'),
- ('\u1b36', '\u1b3a'), ('\u1b3b', '\u1b3b'),
- ('\u1b3c', '\u1b3c'), ('\u1b3d', '\u1b41'),
- ('\u1b42', '\u1b42'), ('\u1b43', '\u1b44'),
- ('\u1b45', '\u1b4b'), ('\u1b50', '\u1b59'),
- ('\u1b6b', '\u1b73'), ('\u1b80', '\u1b81'),
- ('\u1b82', '\u1b82'), ('\u1b83', '\u1ba0'),
- ('\u1ba1', '\u1ba1'), ('\u1ba2', '\u1ba5'),
- ('\u1ba6', '\u1ba7'), ('\u1ba8', '\u1ba9'),
- ('\u1baa', '\u1baa'), ('\u1bab', '\u1bab'),
- ('\u1bac', '\u1bad'), ('\u1bae', '\u1baf'),
- ('\u1bb0', '\u1bb9'), ('\u1bba', '\u1be5'),
- ('\u1be6', '\u1be6'), ('\u1be7', '\u1be7'),
- ('\u1be8', '\u1be9'), ('\u1bea', '\u1bec'),
- ('\u1bed', '\u1bed'), ('\u1bee', '\u1bee'),
- ('\u1bef', '\u1bf1'), ('\u1bf2', '\u1bf3'),
- ('\u1c00', '\u1c23'), ('\u1c24', '\u1c2b'),
- ('\u1c2c', '\u1c33'), ('\u1c34', '\u1c35'),
- ('\u1c36', '\u1c37'), ('\u1c40', '\u1c49'),
- ('\u1c4d', '\u1c4f'), ('\u1c50', '\u1c59'),
- ('\u1c5a', '\u1c77'), ('\u1c78', '\u1c7d'),
- ('\u1cd0', '\u1cd2'), ('\u1cd4', '\u1ce0'),
- ('\u1ce1', '\u1ce1'), ('\u1ce2', '\u1ce8'),
- ('\u1ce9', '\u1cec'), ('\u1ced', '\u1ced'),
- ('\u1cee', '\u1cf1'), ('\u1cf2', '\u1cf3'),
- ('\u1cf4', '\u1cf4'), ('\u1cf5', '\u1cf6'),
- ('\u1d00', '\u1d2b'), ('\u1d2c', '\u1d6a'),
- ('\u1d6b', '\u1d77'), ('\u1d78', '\u1d78'),
- ('\u1d79', '\u1d9a'), ('\u1d9b', '\u1dbf'),
- ('\u1dc0', '\u1de6'), ('\u1dfc', '\u1dff'),
- ('\u1e00', '\u1f15'), ('\u1f18', '\u1f1d'),
- ('\u1f20', '\u1f45'), ('\u1f48', '\u1f4d'),
- ('\u1f50', '\u1f57'), ('\u1f59', '\u1f59'),
- ('\u1f5b', '\u1f5b'), ('\u1f5d', '\u1f5d'),
- ('\u1f5f', '\u1f7d'), ('\u1f80', '\u1fb4'),
- ('\u1fb6', '\u1fbc'), ('\u1fbe', '\u1fbe'),
- ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fcc'),
- ('\u1fd0', '\u1fd3'), ('\u1fd6', '\u1fdb'),
- ('\u1fe0', '\u1fec'), ('\u1ff2', '\u1ff4'),
- ('\u1ff6', '\u1ffc'), ('\u203f', '\u2040'),
- ('\u2054', '\u2054'), ('\u2071', '\u2071'),
- ('\u207f', '\u207f'), ('\u2090', '\u209c'),
- ('\u20d0', '\u20dc'), ('\u20e1', '\u20e1'),
- ('\u20e5', '\u20f0'), ('\u2102', '\u2102'),
- ('\u2107', '\u2107'), ('\u210a', '\u2113'),
- ('\u2115', '\u2115'), ('\u2118', '\u2118'),
- ('\u2119', '\u211d'), ('\u2124', '\u2124'),
- ('\u2126', '\u2126'), ('\u2128', '\u2128'),
- ('\u212a', '\u212d'), ('\u212e', '\u212e'),
- ('\u212f', '\u2134'), ('\u2135', '\u2138'),
- ('\u2139', '\u2139'), ('\u213c', '\u213f'),
- ('\u2145', '\u2149'), ('\u214e', '\u214e'),
- ('\u2160', '\u2182'), ('\u2183', '\u2184'),
- ('\u2185', '\u2188'), ('\u2c00', '\u2c2e'),
- ('\u2c30', '\u2c5e'), ('\u2c60', '\u2c7b'),
- ('\u2c7c', '\u2c7d'), ('\u2c7e', '\u2ce4'),
- ('\u2ceb', '\u2cee'), ('\u2cef', '\u2cf1'),
- ('\u2cf2', '\u2cf3'), ('\u2d00', '\u2d25'),
- ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'),
- ('\u2d30', '\u2d67'), ('\u2d6f', '\u2d6f'),
- ('\u2d7f', '\u2d7f'), ('\u2d80', '\u2d96'),
- ('\u2da0', '\u2da6'), ('\u2da8', '\u2dae'),
- ('\u2db0', '\u2db6'), ('\u2db8', '\u2dbe'),
- ('\u2dc0', '\u2dc6'), ('\u2dc8', '\u2dce'),
- ('\u2dd0', '\u2dd6'), ('\u2dd8', '\u2dde'),
- ('\u2de0', '\u2dff'), ('\u3005', '\u3005'),
- ('\u3006', '\u3006'), ('\u3007', '\u3007'),
- ('\u3021', '\u3029'), ('\u302a', '\u302d'),
- ('\u302e', '\u302f'), ('\u3031', '\u3035'),
- ('\u3038', '\u303a'), ('\u303b', '\u303b'),
- ('\u303c', '\u303c'), ('\u3041', '\u3096'),
- ('\u3099', '\u309a'), ('\u309d', '\u309e'),
- ('\u309f', '\u309f'), ('\u30a1', '\u30fa'),
- ('\u30fc', '\u30fe'), ('\u30ff', '\u30ff'),
- ('\u3105', '\u312d'), ('\u3131', '\u318e'),
- ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'),
- ('\u3400', '\u4db5'), ('\u4e00', '\u9fcc'),
- ('\ua000', '\ua014'), ('\ua015', '\ua015'),
- ('\ua016', '\ua48c'), ('\ua4d0', '\ua4f7'),
- ('\ua4f8', '\ua4fd'), ('\ua500', '\ua60b'),
- ('\ua60c', '\ua60c'), ('\ua610', '\ua61f'),
- ('\ua620', '\ua629'), ('\ua62a', '\ua62b'),
- ('\ua640', '\ua66d'), ('\ua66e', '\ua66e'),
- ('\ua66f', '\ua66f'), ('\ua674', '\ua67d'),
- ('\ua67f', '\ua67f'), ('\ua680', '\ua697'),
- ('\ua69f', '\ua69f'), ('\ua6a0', '\ua6e5'),
- ('\ua6e6', '\ua6ef'), ('\ua6f0', '\ua6f1'),
- ('\ua717', '\ua71f'), ('\ua722', '\ua76f'),
- ('\ua770', '\ua770'), ('\ua771', '\ua787'),
- ('\ua788', '\ua788'), ('\ua78b', '\ua78e'),
- ('\ua790', '\ua793'), ('\ua7a0', '\ua7aa'),
- ('\ua7f8', '\ua7f9'), ('\ua7fa', '\ua7fa'),
- ('\ua7fb', '\ua801'), ('\ua802', '\ua802'),
- ('\ua803', '\ua805'), ('\ua806', '\ua806'),
- ('\ua807', '\ua80a'), ('\ua80b', '\ua80b'),
- ('\ua80c', '\ua822'), ('\ua823', '\ua824'),
- ('\ua825', '\ua826'), ('\ua827', '\ua827'),
- ('\ua840', '\ua873'), ('\ua880', '\ua881'),
- ('\ua882', '\ua8b3'), ('\ua8b4', '\ua8c3'),
- ('\ua8c4', '\ua8c4'), ('\ua8d0', '\ua8d9'),
- ('\ua8e0', '\ua8f1'), ('\ua8f2', '\ua8f7'),
- ('\ua8fb', '\ua8fb'), ('\ua900', '\ua909'),
- ('\ua90a', '\ua925'), ('\ua926', '\ua92d'),
- ('\ua930', '\ua946'), ('\ua947', '\ua951'),
- ('\ua952', '\ua953'), ('\ua960', '\ua97c'),
- ('\ua980', '\ua982'), ('\ua983', '\ua983'),
- ('\ua984', '\ua9b2'), ('\ua9b3', '\ua9b3'),
- ('\ua9b4', '\ua9b5'), ('\ua9b6', '\ua9b9'),
- ('\ua9ba', '\ua9bb'), ('\ua9bc', '\ua9bc'),
- ('\ua9bd', '\ua9c0'), ('\ua9cf', '\ua9cf'),
- ('\ua9d0', '\ua9d9'), ('\uaa00', '\uaa28'),
- ('\uaa29', '\uaa2e'), ('\uaa2f', '\uaa30'),
- ('\uaa31', '\uaa32'), ('\uaa33', '\uaa34'),
- ('\uaa35', '\uaa36'), ('\uaa40', '\uaa42'),
- ('\uaa43', '\uaa43'), ('\uaa44', '\uaa4b'),
- ('\uaa4c', '\uaa4c'), ('\uaa4d', '\uaa4d'),
- ('\uaa50', '\uaa59'), ('\uaa60', '\uaa6f'),
- ('\uaa70', '\uaa70'), ('\uaa71', '\uaa76'),
- ('\uaa7a', '\uaa7a'), ('\uaa7b', '\uaa7b'),
- ('\uaa80', '\uaaaf'), ('\uaab0', '\uaab0'),
- ('\uaab1', '\uaab1'), ('\uaab2', '\uaab4'),
- ('\uaab5', '\uaab6'), ('\uaab7', '\uaab8'),
- ('\uaab9', '\uaabd'), ('\uaabe', '\uaabf'),
- ('\uaac0', '\uaac0'), ('\uaac1', '\uaac1'),
- ('\uaac2', '\uaac2'), ('\uaadb', '\uaadc'),
- ('\uaadd', '\uaadd'), ('\uaae0', '\uaaea'),
- ('\uaaeb', '\uaaeb'), ('\uaaec', '\uaaed'),
- ('\uaaee', '\uaaef'), ('\uaaf2', '\uaaf2'),
- ('\uaaf3', '\uaaf4'), ('\uaaf5', '\uaaf5'),
- ('\uaaf6', '\uaaf6'), ('\uab01', '\uab06'),
- ('\uab09', '\uab0e'), ('\uab11', '\uab16'),
- ('\uab20', '\uab26'), ('\uab28', '\uab2e'),
- ('\uabc0', '\uabe2'), ('\uabe3', '\uabe4'),
- ('\uabe5', '\uabe5'), ('\uabe6', '\uabe7'),
- ('\uabe8', '\uabe8'), ('\uabe9', '\uabea'),
- ('\uabec', '\uabec'), ('\uabed', '\uabed'),
- ('\uabf0', '\uabf9'), ('\uac00', '\ud7a3'),
- ('\ud7b0', '\ud7c6'), ('\ud7cb', '\ud7fb'),
- ('\uf900', '\ufa6d'), ('\ufa70', '\ufad9'),
- ('\ufb00', '\ufb06'), ('\ufb13', '\ufb17'),
- ('\ufb1d', '\ufb1d'), ('\ufb1e', '\ufb1e'),
- ('\ufb1f', '\ufb28'), ('\ufb2a', '\ufb36'),
- ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'),
- ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'),
- ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufc5d'),
- ('\ufc64', '\ufd3d'), ('\ufd50', '\ufd8f'),
- ('\ufd92', '\ufdc7'), ('\ufdf0', '\ufdf9'),
- ('\ufe00', '\ufe0f'), ('\ufe20', '\ufe26'),
- ('\ufe33', '\ufe34'), ('\ufe4d', '\ufe4f'),
- ('\ufe71', '\ufe71'), ('\ufe73', '\ufe73'),
- ('\ufe77', '\ufe77'), ('\ufe79', '\ufe79'),
- ('\ufe7b', '\ufe7b'), ('\ufe7d', '\ufe7d'),
- ('\ufe7f', '\ufefc'), ('\uff10', '\uff19'),
- ('\uff21', '\uff3a'), ('\uff3f', '\uff3f'),
- ('\uff41', '\uff5a'), ('\uff66', '\uff6f'),
- ('\uff70', '\uff70'), ('\uff71', '\uff9d'),
- ('\uff9e', '\uff9f'), ('\uffa0', '\uffbe'),
- ('\uffc2', '\uffc7'), ('\uffca', '\uffcf'),
- ('\uffd2', '\uffd7'), ('\uffda', '\uffdc'),
- ('\U00010000', '\U0001000b'), ('\U0001000d', '\U00010026'),
- ('\U00010028', '\U0001003a'), ('\U0001003c', '\U0001003d'),
- ('\U0001003f', '\U0001004d'), ('\U00010050', '\U0001005d'),
- ('\U00010080', '\U000100fa'), ('\U00010140', '\U00010174'),
- ('\U000101fd', '\U000101fd'), ('\U00010280', '\U0001029c'),
- ('\U000102a0', '\U000102d0'), ('\U00010300', '\U0001031e'),
- ('\U00010330', '\U00010340'), ('\U00010341', '\U00010341'),
- ('\U00010342', '\U00010349'), ('\U0001034a', '\U0001034a'),
- ('\U00010380', '\U0001039d'), ('\U000103a0', '\U000103c3'),
- ('\U000103c8', '\U000103cf'), ('\U000103d1', '\U000103d5'),
- ('\U00010400', '\U0001044f'), ('\U00010450', '\U0001049d'),
- ('\U000104a0', '\U000104a9'), ('\U00010800', '\U00010805'),
- ('\U00010808', '\U00010808'), ('\U0001080a', '\U00010835'),
- ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'),
- ('\U0001083f', '\U00010855'), ('\U00010900', '\U00010915'),
- ('\U00010920', '\U00010939'), ('\U00010980', '\U000109b7'),
- ('\U000109be', '\U000109bf'), ('\U00010a00', '\U00010a00'),
- ('\U00010a01', '\U00010a03'), ('\U00010a05', '\U00010a06'),
- ('\U00010a0c', '\U00010a0f'), ('\U00010a10', '\U00010a13'),
- ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'),
- ('\U00010a38', '\U00010a3a'), ('\U00010a3f', '\U00010a3f'),
- ('\U00010a60', '\U00010a7c'), ('\U00010b00', '\U00010b35'),
- ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'),
- ('\U00010c00', '\U00010c48'), ('\U00011000', '\U00011000'),
- ('\U00011001', '\U00011001'), ('\U00011002', '\U00011002'),
- ('\U00011003', '\U00011037'), ('\U00011038', '\U00011046'),
- ('\U00011066', '\U0001106f'), ('\U00011080', '\U00011081'),
- ('\U00011082', '\U00011082'), ('\U00011083', '\U000110af'),
- ('\U000110b0', '\U000110b2'), ('\U000110b3', '\U000110b6'),
- ('\U000110b7', '\U000110b8'), ('\U000110b9', '\U000110ba'),
- ('\U000110d0', '\U000110e8'), ('\U000110f0', '\U000110f9'),
- ('\U00011100', '\U00011102'), ('\U00011103', '\U00011126'),
- ('\U00011127', '\U0001112b'), ('\U0001112c', '\U0001112c'),
- ('\U0001112d', '\U00011134'), ('\U00011136', '\U0001113f'),
- ('\U00011180', '\U00011181'), ('\U00011182', '\U00011182'),
- ('\U00011183', '\U000111b2'), ('\U000111b3', '\U000111b5'),
- ('\U000111b6', '\U000111be'), ('\U000111bf', '\U000111c0'),
- ('\U000111c1', '\U000111c4'), ('\U000111d0', '\U000111d9'),
- ('\U00011680', '\U000116aa'), ('\U000116ab', '\U000116ab'),
- ('\U000116ac', '\U000116ac'), ('\U000116ad', '\U000116ad'),
- ('\U000116ae', '\U000116af'), ('\U000116b0', '\U000116b5'),
- ('\U000116b6', '\U000116b6'), ('\U000116b7', '\U000116b7'),
- ('\U000116c0', '\U000116c9'), ('\U00012000', '\U0001236e'),
- ('\U00012400', '\U00012462'), ('\U00013000', '\U0001342e'),
- ('\U00016800', '\U00016a38'), ('\U00016f00', '\U00016f44'),
- ('\U00016f50', '\U00016f50'), ('\U00016f51', '\U00016f7e'),
- ('\U00016f8f', '\U00016f92'), ('\U00016f93', '\U00016f9f'),
- ('\U0001b000', '\U0001b001'), ('\U0001d165', '\U0001d166'),
- ('\U0001d167', '\U0001d169'), ('\U0001d16d', '\U0001d172'),
- ('\U0001d17b', '\U0001d182'), ('\U0001d185', '\U0001d18b'),
- ('\U0001d1aa', '\U0001d1ad'), ('\U0001d242', '\U0001d244'),
- ('\U0001d400', '\U0001d454'), ('\U0001d456', '\U0001d49c'),
- ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'),
- ('\U0001d4a5', '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'),
- ('\U0001d4ae', '\U0001d4b9'), ('\U0001d4bb', '\U0001d4bb'),
- ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d505'),
- ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'),
- ('\U0001d516', '\U0001d51c'), ('\U0001d51e', '\U0001d539'),
- ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'),
- ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'),
- ('\U0001d552', '\U0001d6a5'), ('\U0001d6a8', '\U0001d6c0'),
- ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6fa'),
- ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d734'),
- ('\U0001d736', '\U0001d74e'), ('\U0001d750', '\U0001d76e'),
- ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d7a8'),
- ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb'),
- ('\U0001d7ce', '\U0001d7ff'), ('\U0001ee00', '\U0001ee03'),
- ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'),
- ('\U0001ee24', '\U0001ee24'), ('\U0001ee27', '\U0001ee27'),
- ('\U0001ee29', '\U0001ee32'), ('\U0001ee34', '\U0001ee37'),
- ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'),
- ('\U0001ee42', '\U0001ee42'), ('\U0001ee47', '\U0001ee47'),
- ('\U0001ee49', '\U0001ee49'), ('\U0001ee4b', '\U0001ee4b'),
- ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'),
- ('\U0001ee54', '\U0001ee54'), ('\U0001ee57', '\U0001ee57'),
- ('\U0001ee59', '\U0001ee59'), ('\U0001ee5b', '\U0001ee5b'),
- ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'),
- ('\U0001ee61', '\U0001ee62'), ('\U0001ee64', '\U0001ee64'),
- ('\U0001ee67', '\U0001ee6a'), ('\U0001ee6c', '\U0001ee72'),
- ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'),
- ('\U0001ee7e', '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'),
- ('\U0001ee8b', '\U0001ee9b'), ('\U0001eea1', '\U0001eea3'),
- ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'),
- ('\U00020000', '\U0002a6d6'), ('\U0002a700', '\U0002b734'),
- ('\U0002b740', '\U0002b81d'), ('\U0002f800', '\U0002fa1d'),
- ('\U000e0100', '\U000e01ef')
- ];
-
- pub fn XID_Continue(c: char) -> bool {
- super::bsearch_range_table(c, XID_Continue_table)
- }
-
- static XID_Start_table : &'static [(char,char)] = &[
- ('\x41', '\x5a'), ('\x61', '\x7a'),
- ('\xaa', '\xaa'), ('\xb5', '\xb5'),
- ('\xba', '\xba'), ('\xc0', '\xd6'),
- ('\xd8', '\xf6'), ('\xf8', '\u01ba'),
- ('\u01bb', '\u01bb'), ('\u01bc', '\u01bf'),
- ('\u01c0', '\u01c3'), ('\u01c4', '\u0293'),
- ('\u0294', '\u0294'), ('\u0295', '\u02af'),
- ('\u02b0', '\u02c1'), ('\u02c6', '\u02d1'),
- ('\u02e0', '\u02e4'), ('\u02ec', '\u02ec'),
- ('\u02ee', '\u02ee'), ('\u0370', '\u0373'),
- ('\u0374', '\u0374'), ('\u0376', '\u0377'),
- ('\u037b', '\u037d'), ('\u0386', '\u0386'),
- ('\u0388', '\u038a'), ('\u038c', '\u038c'),
- ('\u038e', '\u03a1'), ('\u03a3', '\u03f5'),
- ('\u03f7', '\u0481'), ('\u048a', '\u0527'),
- ('\u0531', '\u0556'), ('\u0559', '\u0559'),
- ('\u0561', '\u0587'), ('\u05d0', '\u05ea'),
- ('\u05f0', '\u05f2'), ('\u0620', '\u063f'),
- ('\u0640', '\u0640'), ('\u0641', '\u064a'),
- ('\u066e', '\u066f'), ('\u0671', '\u06d3'),
- ('\u06d5', '\u06d5'), ('\u06e5', '\u06e6'),
- ('\u06ee', '\u06ef'), ('\u06fa', '\u06fc'),
- ('\u06ff', '\u06ff'), ('\u0710', '\u0710'),
- ('\u0712', '\u072f'), ('\u074d', '\u07a5'),
- ('\u07b1', '\u07b1'), ('\u07ca', '\u07ea'),
- ('\u07f4', '\u07f5'), ('\u07fa', '\u07fa'),
- ('\u0800', '\u0815'), ('\u081a', '\u081a'),
- ('\u0824', '\u0824'), ('\u0828', '\u0828'),
- ('\u0840', '\u0858'), ('\u08a0', '\u08a0'),
- ('\u08a2', '\u08ac'), ('\u0904', '\u0939'),
- ('\u093d', '\u093d'), ('\u0950', '\u0950'),
- ('\u0958', '\u0961'), ('\u0971', '\u0971'),
- ('\u0972', '\u0977'), ('\u0979', '\u097f'),
- ('\u0985', '\u098c'), ('\u098f', '\u0990'),
- ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'),
- ('\u09b2', '\u09b2'), ('\u09b6', '\u09b9'),
- ('\u09bd', '\u09bd'), ('\u09ce', '\u09ce'),
- ('\u09dc', '\u09dd'), ('\u09df', '\u09e1'),
- ('\u09f0', '\u09f1'), ('\u0a05', '\u0a0a'),
- ('\u0a0f', '\u0a10'), ('\u0a13', '\u0a28'),
- ('\u0a2a', '\u0a30'), ('\u0a32', '\u0a33'),
- ('\u0a35', '\u0a36'), ('\u0a38', '\u0a39'),
- ('\u0a59', '\u0a5c'), ('\u0a5e', '\u0a5e'),
- ('\u0a72', '\u0a74'), ('\u0a85', '\u0a8d'),
- ('\u0a8f', '\u0a91'), ('\u0a93', '\u0aa8'),
- ('\u0aaa', '\u0ab0'), ('\u0ab2', '\u0ab3'),
- ('\u0ab5', '\u0ab9'), ('\u0abd', '\u0abd'),
- ('\u0ad0', '\u0ad0'), ('\u0ae0', '\u0ae1'),
- ('\u0b05', '\u0b0c'), ('\u0b0f', '\u0b10'),
- ('\u0b13', '\u0b28'), ('\u0b2a', '\u0b30'),
- ('\u0b32', '\u0b33'), ('\u0b35', '\u0b39'),
- ('\u0b3d', '\u0b3d'), ('\u0b5c', '\u0b5d'),
- ('\u0b5f', '\u0b61'), ('\u0b71', '\u0b71'),
- ('\u0b83', '\u0b83'), ('\u0b85', '\u0b8a'),
- ('\u0b8e', '\u0b90'), ('\u0b92', '\u0b95'),
- ('\u0b99', '\u0b9a'), ('\u0b9c', '\u0b9c'),
- ('\u0b9e', '\u0b9f'), ('\u0ba3', '\u0ba4'),
- ('\u0ba8', '\u0baa'), ('\u0bae', '\u0bb9'),
- ('\u0bd0', '\u0bd0'), ('\u0c05', '\u0c0c'),
- ('\u0c0e', '\u0c10'), ('\u0c12', '\u0c28'),
- ('\u0c2a', '\u0c33'), ('\u0c35', '\u0c39'),
- ('\u0c3d', '\u0c3d'), ('\u0c58', '\u0c59'),
- ('\u0c60', '\u0c61'), ('\u0c85', '\u0c8c'),
- ('\u0c8e', '\u0c90'), ('\u0c92', '\u0ca8'),
- ('\u0caa', '\u0cb3'), ('\u0cb5', '\u0cb9'),
- ('\u0cbd', '\u0cbd'), ('\u0cde', '\u0cde'),
- ('\u0ce0', '\u0ce1'), ('\u0cf1', '\u0cf2'),
- ('\u0d05', '\u0d0c'), ('\u0d0e', '\u0d10'),
- ('\u0d12', '\u0d3a'), ('\u0d3d', '\u0d3d'),
- ('\u0d4e', '\u0d4e'), ('\u0d60', '\u0d61'),
- ('\u0d7a', '\u0d7f'), ('\u0d85', '\u0d96'),
- ('\u0d9a', '\u0db1'), ('\u0db3', '\u0dbb'),
- ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'),
- ('\u0e01', '\u0e30'), ('\u0e32', '\u0e32'),
- ('\u0e40', '\u0e45'), ('\u0e46', '\u0e46'),
- ('\u0e81', '\u0e82'), ('\u0e84', '\u0e84'),
- ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'),
- ('\u0e8d', '\u0e8d'), ('\u0e94', '\u0e97'),
- ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'),
- ('\u0ea5', '\u0ea5'), ('\u0ea7', '\u0ea7'),
- ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'),
- ('\u0eb2', '\u0eb2'), ('\u0ebd', '\u0ebd'),
- ('\u0ec0', '\u0ec4'), ('\u0ec6', '\u0ec6'),
- ('\u0edc', '\u0edf'), ('\u0f00', '\u0f00'),
- ('\u0f40', '\u0f47'), ('\u0f49', '\u0f6c'),
- ('\u0f88', '\u0f8c'), ('\u1000', '\u102a'),
- ('\u103f', '\u103f'), ('\u1050', '\u1055'),
- ('\u105a', '\u105d'), ('\u1061', '\u1061'),
- ('\u1065', '\u1066'), ('\u106e', '\u1070'),
- ('\u1075', '\u1081'), ('\u108e', '\u108e'),
- ('\u10a0', '\u10c5'), ('\u10c7', '\u10c7'),
- ('\u10cd', '\u10cd'), ('\u10d0', '\u10fa'),
- ('\u10fc', '\u10fc'), ('\u10fd', '\u1248'),
- ('\u124a', '\u124d'), ('\u1250', '\u1256'),
- ('\u1258', '\u1258'), ('\u125a', '\u125d'),
- ('\u1260', '\u1288'), ('\u128a', '\u128d'),
- ('\u1290', '\u12b0'), ('\u12b2', '\u12b5'),
- ('\u12b8', '\u12be'), ('\u12c0', '\u12c0'),
- ('\u12c2', '\u12c5'), ('\u12c8', '\u12d6'),
- ('\u12d8', '\u1310'), ('\u1312', '\u1315'),
- ('\u1318', '\u135a'), ('\u1380', '\u138f'),
- ('\u13a0', '\u13f4'), ('\u1401', '\u166c'),
- ('\u166f', '\u167f'), ('\u1681', '\u169a'),
- ('\u16a0', '\u16ea'), ('\u16ee', '\u16f0'),
- ('\u1700', '\u170c'), ('\u170e', '\u1711'),
- ('\u1720', '\u1731'), ('\u1740', '\u1751'),
- ('\u1760', '\u176c'), ('\u176e', '\u1770'),
- ('\u1780', '\u17b3'), ('\u17d7', '\u17d7'),
- ('\u17dc', '\u17dc'), ('\u1820', '\u1842'),
- ('\u1843', '\u1843'), ('\u1844', '\u1877'),
- ('\u1880', '\u18a8'), ('\u18aa', '\u18aa'),
- ('\u18b0', '\u18f5'), ('\u1900', '\u191c'),
- ('\u1950', '\u196d'), ('\u1970', '\u1974'),
- ('\u1980', '\u19ab'), ('\u19c1', '\u19c7'),
- ('\u1a00', '\u1a16'), ('\u1a20', '\u1a54'),
- ('\u1aa7', '\u1aa7'), ('\u1b05', '\u1b33'),
- ('\u1b45', '\u1b4b'), ('\u1b83', '\u1ba0'),
- ('\u1bae', '\u1baf'), ('\u1bba', '\u1be5'),
- ('\u1c00', '\u1c23'), ('\u1c4d', '\u1c4f'),
- ('\u1c5a', '\u1c77'), ('\u1c78', '\u1c7d'),
- ('\u1ce9', '\u1cec'), ('\u1cee', '\u1cf1'),
- ('\u1cf5', '\u1cf6'), ('\u1d00', '\u1d2b'),
- ('\u1d2c', '\u1d6a'), ('\u1d6b', '\u1d77'),
- ('\u1d78', '\u1d78'), ('\u1d79', '\u1d9a'),
- ('\u1d9b', '\u1dbf'), ('\u1e00', '\u1f15'),
- ('\u1f18', '\u1f1d'), ('\u1f20', '\u1f45'),
- ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'),
- ('\u1f59', '\u1f59'), ('\u1f5b', '\u1f5b'),
- ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'),
- ('\u1f80', '\u1fb4'), ('\u1fb6', '\u1fbc'),
- ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'),
- ('\u1fc6', '\u1fcc'), ('\u1fd0', '\u1fd3'),
- ('\u1fd6', '\u1fdb'), ('\u1fe0', '\u1fec'),
- ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ffc'),
- ('\u2071', '\u2071'), ('\u207f', '\u207f'),
- ('\u2090', '\u209c'), ('\u2102', '\u2102'),
- ('\u2107', '\u2107'), ('\u210a', '\u2113'),
- ('\u2115', '\u2115'), ('\u2118', '\u2118'),
- ('\u2119', '\u211d'), ('\u2124', '\u2124'),
- ('\u2126', '\u2126'), ('\u2128', '\u2128'),
- ('\u212a', '\u212d'), ('\u212e', '\u212e'),
- ('\u212f', '\u2134'), ('\u2135', '\u2138'),
- ('\u2139', '\u2139'), ('\u213c', '\u213f'),
- ('\u2145', '\u2149'), ('\u214e', '\u214e'),
- ('\u2160', '\u2182'), ('\u2183', '\u2184'),
- ('\u2185', '\u2188'), ('\u2c00', '\u2c2e'),
- ('\u2c30', '\u2c5e'), ('\u2c60', '\u2c7b'),
- ('\u2c7c', '\u2c7d'), ('\u2c7e', '\u2ce4'),
- ('\u2ceb', '\u2cee'), ('\u2cf2', '\u2cf3'),
- ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'),
- ('\u2d2d', '\u2d2d'), ('\u2d30', '\u2d67'),
- ('\u2d6f', '\u2d6f'), ('\u2d80', '\u2d96'),
- ('\u2da0', '\u2da6'), ('\u2da8', '\u2dae'),
- ('\u2db0', '\u2db6'), ('\u2db8', '\u2dbe'),
- ('\u2dc0', '\u2dc6'), ('\u2dc8', '\u2dce'),
- ('\u2dd0', '\u2dd6'), ('\u2dd8', '\u2dde'),
- ('\u3005', '\u3005'), ('\u3006', '\u3006'),
- ('\u3007', '\u3007'), ('\u3021', '\u3029'),
- ('\u3031', '\u3035'), ('\u3038', '\u303a'),
- ('\u303b', '\u303b'), ('\u303c', '\u303c'),
- ('\u3041', '\u3096'), ('\u309d', '\u309e'),
- ('\u309f', '\u309f'), ('\u30a1', '\u30fa'),
- ('\u30fc', '\u30fe'), ('\u30ff', '\u30ff'),
- ('\u3105', '\u312d'), ('\u3131', '\u318e'),
- ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'),
- ('\u3400', '\u4db5'), ('\u4e00', '\u9fcc'),
- ('\ua000', '\ua014'), ('\ua015', '\ua015'),
- ('\ua016', '\ua48c'), ('\ua4d0', '\ua4f7'),
- ('\ua4f8', '\ua4fd'), ('\ua500', '\ua60b'),
- ('\ua60c', '\ua60c'), ('\ua610', '\ua61f'),
- ('\ua62a', '\ua62b'), ('\ua640', '\ua66d'),
- ('\ua66e', '\ua66e'), ('\ua67f', '\ua67f'),
- ('\ua680', '\ua697'), ('\ua6a0', '\ua6e5'),
- ('\ua6e6', '\ua6ef'), ('\ua717', '\ua71f'),
- ('\ua722', '\ua76f'), ('\ua770', '\ua770'),
- ('\ua771', '\ua787'), ('\ua788', '\ua788'),
- ('\ua78b', '\ua78e'), ('\ua790', '\ua793'),
- ('\ua7a0', '\ua7aa'), ('\ua7f8', '\ua7f9'),
- ('\ua7fa', '\ua7fa'), ('\ua7fb', '\ua801'),
- ('\ua803', '\ua805'), ('\ua807', '\ua80a'),
- ('\ua80c', '\ua822'), ('\ua840', '\ua873'),
- ('\ua882', '\ua8b3'), ('\ua8f2', '\ua8f7'),
- ('\ua8fb', '\ua8fb'), ('\ua90a', '\ua925'),
- ('\ua930', '\ua946'), ('\ua960', '\ua97c'),
- ('\ua984', '\ua9b2'), ('\ua9cf', '\ua9cf'),
- ('\uaa00', '\uaa28'), ('\uaa40', '\uaa42'),
- ('\uaa44', '\uaa4b'), ('\uaa60', '\uaa6f'),
- ('\uaa70', '\uaa70'), ('\uaa71', '\uaa76'),
- ('\uaa7a', '\uaa7a'), ('\uaa80', '\uaaaf'),
- ('\uaab1', '\uaab1'), ('\uaab5', '\uaab6'),
- ('\uaab9', '\uaabd'), ('\uaac0', '\uaac0'),
- ('\uaac2', '\uaac2'), ('\uaadb', '\uaadc'),
- ('\uaadd', '\uaadd'), ('\uaae0', '\uaaea'),
- ('\uaaf2', '\uaaf2'), ('\uaaf3', '\uaaf4'),
- ('\uab01', '\uab06'), ('\uab09', '\uab0e'),
- ('\uab11', '\uab16'), ('\uab20', '\uab26'),
- ('\uab28', '\uab2e'), ('\uabc0', '\uabe2'),
- ('\uac00', '\ud7a3'), ('\ud7b0', '\ud7c6'),
- ('\ud7cb', '\ud7fb'), ('\uf900', '\ufa6d'),
- ('\ufa70', '\ufad9'), ('\ufb00', '\ufb06'),
- ('\ufb13', '\ufb17'), ('\ufb1d', '\ufb1d'),
- ('\ufb1f', '\ufb28'), ('\ufb2a', '\ufb36'),
- ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'),
- ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'),
- ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufc5d'),
- ('\ufc64', '\ufd3d'), ('\ufd50', '\ufd8f'),
- ('\ufd92', '\ufdc7'), ('\ufdf0', '\ufdf9'),
- ('\ufe71', '\ufe71'), ('\ufe73', '\ufe73'),
- ('\ufe77', '\ufe77'), ('\ufe79', '\ufe79'),
- ('\ufe7b', '\ufe7b'), ('\ufe7d', '\ufe7d'),
- ('\ufe7f', '\ufefc'), ('\uff21', '\uff3a'),
- ('\uff41', '\uff5a'), ('\uff66', '\uff6f'),
- ('\uff70', '\uff70'), ('\uff71', '\uff9d'),
- ('\uffa0', '\uffbe'), ('\uffc2', '\uffc7'),
- ('\uffca', '\uffcf'), ('\uffd2', '\uffd7'),
- ('\uffda', '\uffdc'), ('\U00010000', '\U0001000b'),
- ('\U0001000d', '\U00010026'), ('\U00010028', '\U0001003a'),
- ('\U0001003c', '\U0001003d'), ('\U0001003f', '\U0001004d'),
- ('\U00010050', '\U0001005d'), ('\U00010080', '\U000100fa'),
- ('\U00010140', '\U00010174'), ('\U00010280', '\U0001029c'),
- ('\U000102a0', '\U000102d0'), ('\U00010300', '\U0001031e'),
- ('\U00010330', '\U00010340'), ('\U00010341', '\U00010341'),
- ('\U00010342', '\U00010349'), ('\U0001034a', '\U0001034a'),
- ('\U00010380', '\U0001039d'), ('\U000103a0', '\U000103c3'),
- ('\U000103c8', '\U000103cf'), ('\U000103d1', '\U000103d5'),
- ('\U00010400', '\U0001044f'), ('\U00010450', '\U0001049d'),
- ('\U00010800', '\U00010805'), ('\U00010808', '\U00010808'),
- ('\U0001080a', '\U00010835'), ('\U00010837', '\U00010838'),
- ('\U0001083c', '\U0001083c'), ('\U0001083f', '\U00010855'),
- ('\U00010900', '\U00010915'), ('\U00010920', '\U00010939'),
- ('\U00010980', '\U000109b7'), ('\U000109be', '\U000109bf'),
- ('\U00010a00', '\U00010a00'), ('\U00010a10', '\U00010a13'),
- ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'),
- ('\U00010a60', '\U00010a7c'), ('\U00010b00', '\U00010b35'),
- ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'),
- ('\U00010c00', '\U00010c48'), ('\U00011003', '\U00011037'),
- ('\U00011083', '\U000110af'), ('\U000110d0', '\U000110e8'),
- ('\U00011103', '\U00011126'), ('\U00011183', '\U000111b2'),
- ('\U000111c1', '\U000111c4'), ('\U00011680', '\U000116aa'),
- ('\U00012000', '\U0001236e'), ('\U00012400', '\U00012462'),
- ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'),
- ('\U00016f00', '\U00016f44'), ('\U00016f50', '\U00016f50'),
- ('\U00016f93', '\U00016f9f'), ('\U0001b000', '\U0001b001'),
- ('\U0001d400', '\U0001d454'), ('\U0001d456', '\U0001d49c'),
- ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'),
- ('\U0001d4a5', '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'),
- ('\U0001d4ae', '\U0001d4b9'), ('\U0001d4bb', '\U0001d4bb'),
- ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d505'),
- ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'),
- ('\U0001d516', '\U0001d51c'), ('\U0001d51e', '\U0001d539'),
- ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'),
- ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'),
- ('\U0001d552', '\U0001d6a5'), ('\U0001d6a8', '\U0001d6c0'),
- ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6fa'),
- ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d734'),
- ('\U0001d736', '\U0001d74e'), ('\U0001d750', '\U0001d76e'),
- ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d7a8'),
- ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb'),
- ('\U0001ee00', '\U0001ee03'), ('\U0001ee05', '\U0001ee1f'),
- ('\U0001ee21', '\U0001ee22'), ('\U0001ee24', '\U0001ee24'),
- ('\U0001ee27', '\U0001ee27'), ('\U0001ee29', '\U0001ee32'),
- ('\U0001ee34', '\U0001ee37'), ('\U0001ee39', '\U0001ee39'),
- ('\U0001ee3b', '\U0001ee3b'), ('\U0001ee42', '\U0001ee42'),
- ('\U0001ee47', '\U0001ee47'), ('\U0001ee49', '\U0001ee49'),
- ('\U0001ee4b', '\U0001ee4b'), ('\U0001ee4d', '\U0001ee4f'),
- ('\U0001ee51', '\U0001ee52'), ('\U0001ee54', '\U0001ee54'),
- ('\U0001ee57', '\U0001ee57'), ('\U0001ee59', '\U0001ee59'),
- ('\U0001ee5b', '\U0001ee5b'), ('\U0001ee5d', '\U0001ee5d'),
- ('\U0001ee5f', '\U0001ee5f'), ('\U0001ee61', '\U0001ee62'),
- ('\U0001ee64', '\U0001ee64'), ('\U0001ee67', '\U0001ee6a'),
- ('\U0001ee6c', '\U0001ee72'), ('\U0001ee74', '\U0001ee77'),
- ('\U0001ee79', '\U0001ee7c'), ('\U0001ee7e', '\U0001ee7e'),
- ('\U0001ee80', '\U0001ee89'), ('\U0001ee8b', '\U0001ee9b'),
- ('\U0001eea1', '\U0001eea3'), ('\U0001eea5', '\U0001eea9'),
- ('\U0001eeab', '\U0001eebb'), ('\U00020000', '\U0002a6d6'),
- ('\U0002a700', '\U0002b734'), ('\U0002b740', '\U0002b81d'),
- ('\U0002f800', '\U0002fa1d')
- ];
-
- pub fn XID_Start(c: char) -> bool {
- super::bsearch_range_table(c, XID_Start_table)
- }
-
-}
-
-pub mod property {
- static White_Space_table : &'static [(char,char)] = &[
- ('\x09', '\x0d'), ('\x20', '\x20'),
- ('\x85', '\x85'), ('\xa0', '\xa0'),
- ('\u1680', '\u1680'), ('\u2000', '\u200a'),
- ('\u2028', '\u2028'), ('\u2029', '\u2029'),
- ('\u202f', '\u202f'), ('\u205f', '\u205f'),
- ('\u3000', '\u3000')
- ];
-
- pub fn White_Space(c: char) -> bool {
- super::bsearch_range_table(c, White_Space_table)
- }
-
-}
-
-pub mod conversions {
- use cmp::{Equal, Less, Greater};
- use slice::ImmutableVector;
- use tuple::Tuple2;
- use option::{Option, Some, None};
-
- pub fn to_lower(c: char) -> char {
- match bsearch_case_table(c, LuLl_table) {
- None => c,
- Some(index) => LuLl_table[index].val1()
- }
- }
-
- pub fn to_upper(c: char) -> char {
- match bsearch_case_table(c, LlLu_table) {
- None => c,
- Some(index) => LlLu_table[index].val1()
- }
- }
-
- fn bsearch_case_table(c: char, table: &'static [(char, char)]) -> Option<uint> {
- table.bsearch(|&(key, _)| {
- if c == key { Equal }
- else if key < c { Less }
- else { Greater }
- })
- }
-
- static LuLl_table : &'static [(char, char)] = &[
- ('\x41', '\x61'), ('\x42', '\x62'),
- ('\x43', '\x63'), ('\x44', '\x64'),
- ('\x45', '\x65'), ('\x46', '\x66'),
- ('\x47', '\x67'), ('\x48', '\x68'),
- ('\x49', '\x69'), ('\x4a', '\x6a'),
- ('\x4b', '\x6b'), ('\x4c', '\x6c'),
- ('\x4d', '\x6d'), ('\x4e', '\x6e'),
- ('\x4f', '\x6f'), ('\x50', '\x70'),
- ('\x51', '\x71'), ('\x52', '\x72'),
- ('\x53', '\x73'), ('\x54', '\x74'),
- ('\x55', '\x75'), ('\x56', '\x76'),
- ('\x57', '\x77'), ('\x58', '\x78'),
- ('\x59', '\x79'), ('\x5a', '\x7a'),
- ('\xc0', '\xe0'), ('\xc1', '\xe1'),
- ('\xc2', '\xe2'), ('\xc3', '\xe3'),
- ('\xc4', '\xe4'), ('\xc5', '\xe5'),
- ('\xc6', '\xe6'), ('\xc7', '\xe7'),
- ('\xc8', '\xe8'), ('\xc9', '\xe9'),
- ('\xca', '\xea'), ('\xcb', '\xeb'),
- ('\xcc', '\xec'), ('\xcd', '\xed'),
- ('\xce', '\xee'), ('\xcf', '\xef'),
- ('\xd0', '\xf0'), ('\xd1', '\xf1'),
- ('\xd2', '\xf2'), ('\xd3', '\xf3'),
- ('\xd4', '\xf4'), ('\xd5', '\xf5'),
- ('\xd6', '\xf6'), ('\xd8', '\xf8'),
- ('\xd9', '\xf9'), ('\xda', '\xfa'),
- ('\xdb', '\xfb'), ('\xdc', '\xfc'),
- ('\xdd', '\xfd'), ('\xde', '\xfe'),
- ('\u0100', '\u0101'), ('\u0102', '\u0103'),
- ('\u0104', '\u0105'), ('\u0106', '\u0107'),
- ('\u0108', '\u0109'), ('\u010a', '\u010b'),
- ('\u010c', '\u010d'), ('\u010e', '\u010f'),
- ('\u0110', '\u0111'), ('\u0112', '\u0113'),
- ('\u0114', '\u0115'), ('\u0116', '\u0117'),
- ('\u0118', '\u0119'), ('\u011a', '\u011b'),
- ('\u011c', '\u011d'), ('\u011e', '\u011f'),
- ('\u0120', '\u0121'), ('\u0122', '\u0123'),
- ('\u0124', '\u0125'), ('\u0126', '\u0127'),
- ('\u0128', '\u0129'), ('\u012a', '\u012b'),
- ('\u012c', '\u012d'), ('\u012e', '\u012f'),
- ('\u0130', '\x69'), ('\u0132', '\u0133'),
- ('\u0134', '\u0135'), ('\u0136', '\u0137'),
- ('\u0139', '\u013a'), ('\u013b', '\u013c'),
- ('\u013d', '\u013e'), ('\u013f', '\u0140'),
- ('\u0141', '\u0142'), ('\u0143', '\u0144'),
- ('\u0145', '\u0146'), ('\u0147', '\u0148'),
- ('\u014a', '\u014b'), ('\u014c', '\u014d'),
- ('\u014e', '\u014f'), ('\u0150', '\u0151'),
- ('\u0152', '\u0153'), ('\u0154', '\u0155'),
- ('\u0156', '\u0157'), ('\u0158', '\u0159'),
- ('\u015a', '\u015b'), ('\u015c', '\u015d'),
- ('\u015e', '\u015f'), ('\u0160', '\u0161'),
- ('\u0162', '\u0163'), ('\u0164', '\u0165'),
- ('\u0166', '\u0167'), ('\u0168', '\u0169'),
- ('\u016a', '\u016b'), ('\u016c', '\u016d'),
- ('\u016e', '\u016f'), ('\u0170', '\u0171'),
- ('\u0172', '\u0173'), ('\u0174', '\u0175'),
- ('\u0176', '\u0177'), ('\u0178', '\xff'),
- ('\u0179', '\u017a'), ('\u017b', '\u017c'),
- ('\u017d', '\u017e'), ('\u0181', '\u0253'),
- ('\u0182', '\u0183'), ('\u0184', '\u0185'),
- ('\u0186', '\u0254'), ('\u0187', '\u0188'),
- ('\u0189', '\u0256'), ('\u018a', '\u0257'),
- ('\u018b', '\u018c'), ('\u018e', '\u01dd'),
- ('\u018f', '\u0259'), ('\u0190', '\u025b'),
- ('\u0191', '\u0192'), ('\u0193', '\u0260'),
- ('\u0194', '\u0263'), ('\u0196', '\u0269'),
- ('\u0197', '\u0268'), ('\u0198', '\u0199'),
- ('\u019c', '\u026f'), ('\u019d', '\u0272'),
- ('\u019f', '\u0275'), ('\u01a0', '\u01a1'),
- ('\u01a2', '\u01a3'), ('\u01a4', '\u01a5'),
- ('\u01a6', '\u0280'), ('\u01a7', '\u01a8'),
- ('\u01a9', '\u0283'), ('\u01ac', '\u01ad'),
- ('\u01ae', '\u0288'), ('\u01af', '\u01b0'),
- ('\u01b1', '\u028a'), ('\u01b2', '\u028b'),
- ('\u01b3', '\u01b4'), ('\u01b5', '\u01b6'),
- ('\u01b7', '\u0292'), ('\u01b8', '\u01b9'),
- ('\u01bc', '\u01bd'), ('\u01c4', '\u01c6'),
- ('\u01c7', '\u01c9'), ('\u01ca', '\u01cc'),
- ('\u01cd', '\u01ce'), ('\u01cf', '\u01d0'),
- ('\u01d1', '\u01d2'), ('\u01d3', '\u01d4'),
- ('\u01d5', '\u01d6'), ('\u01d7', '\u01d8'),
- ('\u01d9', '\u01da'), ('\u01db', '\u01dc'),
- ('\u01de', '\u01df'), ('\u01e0', '\u01e1'),
- ('\u01e2', '\u01e3'), ('\u01e4', '\u01e5'),
- ('\u01e6', '\u01e7'), ('\u01e8', '\u01e9'),
- ('\u01ea', '\u01eb'), ('\u01ec', '\u01ed'),
- ('\u01ee', '\u01ef'), ('\u01f1', '\u01f3'),
- ('\u01f4', '\u01f5'), ('\u01f6', '\u0195'),
- ('\u01f7', '\u01bf'), ('\u01f8', '\u01f9'),
- ('\u01fa', '\u01fb'), ('\u01fc', '\u01fd'),
- ('\u01fe', '\u01ff'), ('\u0200', '\u0201'),
- ('\u0202', '\u0203'), ('\u0204', '\u0205'),
- ('\u0206', '\u0207'), ('\u0208', '\u0209'),
- ('\u020a', '\u020b'), ('\u020c', '\u020d'),
- ('\u020e', '\u020f'), ('\u0210', '\u0211'),
- ('\u0212', '\u0213'), ('\u0214', '\u0215'),
- ('\u0216', '\u0217'), ('\u0218', '\u0219'),
- ('\u021a', '\u021b'), ('\u021c', '\u021d'),
- ('\u021e', '\u021f'), ('\u0220', '\u019e'),
- ('\u0222', '\u0223'), ('\u0224', '\u0225'),
- ('\u0226', '\u0227'), ('\u0228', '\u0229'),
- ('\u022a', '\u022b'), ('\u022c', '\u022d'),
- ('\u022e', '\u022f'), ('\u0230', '\u0231'),
- ('\u0232', '\u0233'), ('\u023a', '\u2c65'),
- ('\u023b', '\u023c'), ('\u023d', '\u019a'),
- ('\u023e', '\u2c66'), ('\u0241', '\u0242'),
- ('\u0243', '\u0180'), ('\u0244', '\u0289'),
- ('\u0245', '\u028c'), ('\u0246', '\u0247'),
- ('\u0248', '\u0249'), ('\u024a', '\u024b'),
- ('\u024c', '\u024d'), ('\u024e', '\u024f'),
- ('\u0370', '\u0371'), ('\u0372', '\u0373'),
- ('\u0376', '\u0377'), ('\u0386', '\u03ac'),
- ('\u0388', '\u03ad'), ('\u0389', '\u03ae'),
- ('\u038a', '\u03af'), ('\u038c', '\u03cc'),
- ('\u038e', '\u03cd'), ('\u038f', '\u03ce'),
- ('\u0391', '\u03b1'), ('\u0392', '\u03b2'),
- ('\u0393', '\u03b3'), ('\u0394', '\u03b4'),
- ('\u0395', '\u03b5'), ('\u0396', '\u03b6'),
- ('\u0397', '\u03b7'), ('\u0398', '\u03b8'),
- ('\u0399', '\u03b9'), ('\u039a', '\u03ba'),
- ('\u039b', '\u03bb'), ('\u039c', '\u03bc'),
- ('\u039d', '\u03bd'), ('\u039e', '\u03be'),
- ('\u039f', '\u03bf'), ('\u03a0', '\u03c0'),
- ('\u03a1', '\u03c1'), ('\u03a3', '\u03c3'),
- ('\u03a4', '\u03c4'), ('\u03a5', '\u03c5'),
- ('\u03a6', '\u03c6'), ('\u03a7', '\u03c7'),
- ('\u03a8', '\u03c8'), ('\u03a9', '\u03c9'),
- ('\u03aa', '\u03ca'), ('\u03ab', '\u03cb'),
- ('\u03cf', '\u03d7'), ('\u03d8', '\u03d9'),
- ('\u03da', '\u03db'), ('\u03dc', '\u03dd'),
- ('\u03de', '\u03df'), ('\u03e0', '\u03e1'),
- ('\u03e2', '\u03e3'), ('\u03e4', '\u03e5'),
- ('\u03e6', '\u03e7'), ('\u03e8', '\u03e9'),
- ('\u03ea', '\u03eb'), ('\u03ec', '\u03ed'),
- ('\u03ee', '\u03ef'), ('\u03f4', '\u03b8'),
- ('\u03f7', '\u03f8'), ('\u03f9', '\u03f2'),
- ('\u03fa', '\u03fb'), ('\u03fd', '\u037b'),
- ('\u03fe', '\u037c'), ('\u03ff', '\u037d'),
- ('\u0400', '\u0450'), ('\u0401', '\u0451'),
- ('\u0402', '\u0452'), ('\u0403', '\u0453'),
- ('\u0404', '\u0454'), ('\u0405', '\u0455'),
- ('\u0406', '\u0456'), ('\u0407', '\u0457'),
- ('\u0408', '\u0458'), ('\u0409', '\u0459'),
- ('\u040a', '\u045a'), ('\u040b', '\u045b'),
- ('\u040c', '\u045c'), ('\u040d', '\u045d'),
- ('\u040e', '\u045e'), ('\u040f', '\u045f'),
- ('\u0410', '\u0430'), ('\u0411', '\u0431'),
- ('\u0412', '\u0432'), ('\u0413', '\u0433'),
- ('\u0414', '\u0434'), ('\u0415', '\u0435'),
- ('\u0416', '\u0436'), ('\u0417', '\u0437'),
- ('\u0418', '\u0438'), ('\u0419', '\u0439'),
- ('\u041a', '\u043a'), ('\u041b', '\u043b'),
- ('\u041c', '\u043c'), ('\u041d', '\u043d'),
- ('\u041e', '\u043e'), ('\u041f', '\u043f'),
- ('\u0420', '\u0440'), ('\u0421', '\u0441'),
- ('\u0422', '\u0442'), ('\u0423', '\u0443'),
- ('\u0424', '\u0444'), ('\u0425', '\u0445'),
- ('\u0426', '\u0446'), ('\u0427', '\u0447'),
- ('\u0428', '\u0448'), ('\u0429', '\u0449'),
- ('\u042a', '\u044a'), ('\u042b', '\u044b'),
- ('\u042c', '\u044c'), ('\u042d', '\u044d'),
- ('\u042e', '\u044e'), ('\u042f', '\u044f'),
- ('\u0460', '\u0461'), ('\u0462', '\u0463'),
- ('\u0464', '\u0465'), ('\u0466', '\u0467'),
- ('\u0468', '\u0469'), ('\u046a', '\u046b'),
- ('\u046c', '\u046d'), ('\u046e', '\u046f'),
- ('\u0470', '\u0471'), ('\u0472', '\u0473'),
- ('\u0474', '\u0475'), ('\u0476', '\u0477'),
- ('\u0478', '\u0479'), ('\u047a', '\u047b'),
- ('\u047c', '\u047d'), ('\u047e', '\u047f'),
- ('\u0480', '\u0481'), ('\u048a', '\u048b'),
- ('\u048c', '\u048d'), ('\u048e', '\u048f'),
- ('\u0490', '\u0491'), ('\u0492', '\u0493'),
- ('\u0494', '\u0495'), ('\u0496', '\u0497'),
- ('\u0498', '\u0499'), ('\u049a', '\u049b'),
- ('\u049c', '\u049d'), ('\u049e', '\u049f'),
- ('\u04a0', '\u04a1'), ('\u04a2', '\u04a3'),
- ('\u04a4', '\u04a5'), ('\u04a6', '\u04a7'),
- ('\u04a8', '\u04a9'), ('\u04aa', '\u04ab'),
- ('\u04ac', '\u04ad'), ('\u04ae', '\u04af'),
- ('\u04b0', '\u04b1'), ('\u04b2', '\u04b3'),
- ('\u04b4', '\u04b5'), ('\u04b6', '\u04b7'),
- ('\u04b8', '\u04b9'), ('\u04ba', '\u04bb'),
- ('\u04bc', '\u04bd'), ('\u04be', '\u04bf'),
- ('\u04c0', '\u04cf'), ('\u04c1', '\u04c2'),
- ('\u04c3', '\u04c4'), ('\u04c5', '\u04c6'),
- ('\u04c7', '\u04c8'), ('\u04c9', '\u04ca'),
- ('\u04cb', '\u04cc'), ('\u04cd', '\u04ce'),
- ('\u04d0', '\u04d1'), ('\u04d2', '\u04d3'),
- ('\u04d4', '\u04d5'), ('\u04d6', '\u04d7'),
- ('\u04d8', '\u04d9'), ('\u04da', '\u04db'),
- ('\u04dc', '\u04dd'), ('\u04de', '\u04df'),
- ('\u04e0', '\u04e1'), ('\u04e2', '\u04e3'),
- ('\u04e4', '\u04e5'), ('\u04e6', '\u04e7'),
- ('\u04e8', '\u04e9'), ('\u04ea', '\u04eb'),
- ('\u04ec', '\u04ed'), ('\u04ee', '\u04ef'),
- ('\u04f0', '\u04f1'), ('\u04f2', '\u04f3'),
- ('\u04f4', '\u04f5'), ('\u04f6', '\u04f7'),
- ('\u04f8', '\u04f9'), ('\u04fa', '\u04fb'),
- ('\u04fc', '\u04fd'), ('\u04fe', '\u04ff'),
- ('\u0500', '\u0501'), ('\u0502', '\u0503'),
- ('\u0504', '\u0505'), ('\u0506', '\u0507'),
- ('\u0508', '\u0509'), ('\u050a', '\u050b'),
- ('\u050c', '\u050d'), ('\u050e', '\u050f'),
- ('\u0510', '\u0511'), ('\u0512', '\u0513'),
- ('\u0514', '\u0515'), ('\u0516', '\u0517'),
- ('\u0518', '\u0519'), ('\u051a', '\u051b'),
- ('\u051c', '\u051d'), ('\u051e', '\u051f'),
- ('\u0520', '\u0521'), ('\u0522', '\u0523'),
- ('\u0524', '\u0525'), ('\u0526', '\u0527'),
- ('\u0531', '\u0561'), ('\u0532', '\u0562'),
- ('\u0533', '\u0563'), ('\u0534', '\u0564'),
- ('\u0535', '\u0565'), ('\u0536', '\u0566'),
- ('\u0537', '\u0567'), ('\u0538', '\u0568'),
- ('\u0539', '\u0569'), ('\u053a', '\u056a'),
- ('\u053b', '\u056b'), ('\u053c', '\u056c'),
- ('\u053d', '\u056d'), ('\u053e', '\u056e'),
- ('\u053f', '\u056f'), ('\u0540', '\u0570'),
- ('\u0541', '\u0571'), ('\u0542', '\u0572'),
- ('\u0543', '\u0573'), ('\u0544', '\u0574'),
- ('\u0545', '\u0575'), ('\u0546', '\u0576'),
- ('\u0547', '\u0577'), ('\u0548', '\u0578'),
- ('\u0549', '\u0579'), ('\u054a', '\u057a'),
- ('\u054b', '\u057b'), ('\u054c', '\u057c'),
- ('\u054d', '\u057d'), ('\u054e', '\u057e'),
- ('\u054f', '\u057f'), ('\u0550', '\u0580'),
- ('\u0551', '\u0581'), ('\u0552', '\u0582'),
- ('\u0553', '\u0583'), ('\u0554', '\u0584'),
- ('\u0555', '\u0585'), ('\u0556', '\u0586'),
- ('\u10a0', '\u2d00'), ('\u10a1', '\u2d01'),
- ('\u10a2', '\u2d02'), ('\u10a3', '\u2d03'),
- ('\u10a4', '\u2d04'), ('\u10a5', '\u2d05'),
- ('\u10a6', '\u2d06'), ('\u10a7', '\u2d07'),
- ('\u10a8', '\u2d08'), ('\u10a9', '\u2d09'),
- ('\u10aa', '\u2d0a'), ('\u10ab', '\u2d0b'),
- ('\u10ac', '\u2d0c'), ('\u10ad', '\u2d0d'),
- ('\u10ae', '\u2d0e'), ('\u10af', '\u2d0f'),
- ('\u10b0', '\u2d10'), ('\u10b1', '\u2d11'),
- ('\u10b2', '\u2d12'), ('\u10b3', '\u2d13'),
- ('\u10b4', '\u2d14'), ('\u10b5', '\u2d15'),
- ('\u10b6', '\u2d16'), ('\u10b7', '\u2d17'),
- ('\u10b8', '\u2d18'), ('\u10b9', '\u2d19'),
- ('\u10ba', '\u2d1a'), ('\u10bb', '\u2d1b'),
- ('\u10bc', '\u2d1c'), ('\u10bd', '\u2d1d'),
- ('\u10be', '\u2d1e'), ('\u10bf', '\u2d1f'),
- ('\u10c0', '\u2d20'), ('\u10c1', '\u2d21'),
- ('\u10c2', '\u2d22'), ('\u10c3', '\u2d23'),
- ('\u10c4', '\u2d24'), ('\u10c5', '\u2d25'),
- ('\u10c7', '\u2d27'), ('\u10cd', '\u2d2d'),
- ('\u1e00', '\u1e01'), ('\u1e02', '\u1e03'),
- ('\u1e04', '\u1e05'), ('\u1e06', '\u1e07'),
- ('\u1e08', '\u1e09'), ('\u1e0a', '\u1e0b'),
- ('\u1e0c', '\u1e0d'), ('\u1e0e', '\u1e0f'),
- ('\u1e10', '\u1e11'), ('\u1e12', '\u1e13'),
- ('\u1e14', '\u1e15'), ('\u1e16', '\u1e17'),
- ('\u1e18', '\u1e19'), ('\u1e1a', '\u1e1b'),
- ('\u1e1c', '\u1e1d'), ('\u1e1e', '\u1e1f'),
- ('\u1e20', '\u1e21'), ('\u1e22', '\u1e23'),
- ('\u1e24', '\u1e25'), ('\u1e26', '\u1e27'),
- ('\u1e28', '\u1e29'), ('\u1e2a', '\u1e2b'),
- ('\u1e2c', '\u1e2d'), ('\u1e2e', '\u1e2f'),
- ('\u1e30', '\u1e31'), ('\u1e32', '\u1e33'),
- ('\u1e34', '\u1e35'), ('\u1e36', '\u1e37'),
- ('\u1e38', '\u1e39'), ('\u1e3a', '\u1e3b'),
- ('\u1e3c', '\u1e3d'), ('\u1e3e', '\u1e3f'),
- ('\u1e40', '\u1e41'), ('\u1e42', '\u1e43'),
- ('\u1e44', '\u1e45'), ('\u1e46', '\u1e47'),
- ('\u1e48', '\u1e49'), ('\u1e4a', '\u1e4b'),
- ('\u1e4c', '\u1e4d'), ('\u1e4e', '\u1e4f'),
- ('\u1e50', '\u1e51'), ('\u1e52', '\u1e53'),
- ('\u1e54', '\u1e55'), ('\u1e56', '\u1e57'),
- ('\u1e58', '\u1e59'), ('\u1e5a', '\u1e5b'),
- ('\u1e5c', '\u1e5d'), ('\u1e5e', '\u1e5f'),
- ('\u1e60', '\u1e61'), ('\u1e62', '\u1e63'),
- ('\u1e64', '\u1e65'), ('\u1e66', '\u1e67'),
- ('\u1e68', '\u1e69'), ('\u1e6a', '\u1e6b'),
- ('\u1e6c', '\u1e6d'), ('\u1e6e', '\u1e6f'),
- ('\u1e70', '\u1e71'), ('\u1e72', '\u1e73'),
- ('\u1e74', '\u1e75'), ('\u1e76', '\u1e77'),
- ('\u1e78', '\u1e79'), ('\u1e7a', '\u1e7b'),
- ('\u1e7c', '\u1e7d'), ('\u1e7e', '\u1e7f'),
- ('\u1e80', '\u1e81'), ('\u1e82', '\u1e83'),
- ('\u1e84', '\u1e85'), ('\u1e86', '\u1e87'),
- ('\u1e88', '\u1e89'), ('\u1e8a', '\u1e8b'),
- ('\u1e8c', '\u1e8d'), ('\u1e8e', '\u1e8f'),
- ('\u1e90', '\u1e91'), ('\u1e92', '\u1e93'),
- ('\u1e94', '\u1e95'), ('\u1e9e', '\xdf'),
- ('\u1ea0', '\u1ea1'), ('\u1ea2', '\u1ea3'),
- ('\u1ea4', '\u1ea5'), ('\u1ea6', '\u1ea7'),
- ('\u1ea8', '\u1ea9'), ('\u1eaa', '\u1eab'),
- ('\u1eac', '\u1ead'), ('\u1eae', '\u1eaf'),
- ('\u1eb0', '\u1eb1'), ('\u1eb2', '\u1eb3'),
- ('\u1eb4', '\u1eb5'), ('\u1eb6', '\u1eb7'),
- ('\u1eb8', '\u1eb9'), ('\u1eba', '\u1ebb'),
- ('\u1ebc', '\u1ebd'), ('\u1ebe', '\u1ebf'),
- ('\u1ec0', '\u1ec1'), ('\u1ec2', '\u1ec3'),
- ('\u1ec4', '\u1ec5'), ('\u1ec6', '\u1ec7'),
- ('\u1ec8', '\u1ec9'), ('\u1eca', '\u1ecb'),
- ('\u1ecc', '\u1ecd'), ('\u1ece', '\u1ecf'),
- ('\u1ed0', '\u1ed1'), ('\u1ed2', '\u1ed3'),
- ('\u1ed4', '\u1ed5'), ('\u1ed6', '\u1ed7'),
- ('\u1ed8', '\u1ed9'), ('\u1eda', '\u1edb'),
- ('\u1edc', '\u1edd'), ('\u1ede', '\u1edf'),
- ('\u1ee0', '\u1ee1'), ('\u1ee2', '\u1ee3'),
- ('\u1ee4', '\u1ee5'), ('\u1ee6', '\u1ee7'),
- ('\u1ee8', '\u1ee9'), ('\u1eea', '\u1eeb'),
- ('\u1eec', '\u1eed'), ('\u1eee', '\u1eef'),
- ('\u1ef0', '\u1ef1'), ('\u1ef2', '\u1ef3'),
- ('\u1ef4', '\u1ef5'), ('\u1ef6', '\u1ef7'),
- ('\u1ef8', '\u1ef9'), ('\u1efa', '\u1efb'),
- ('\u1efc', '\u1efd'), ('\u1efe', '\u1eff'),
- ('\u1f08', '\u1f00'), ('\u1f09', '\u1f01'),
- ('\u1f0a', '\u1f02'), ('\u1f0b', '\u1f03'),
- ('\u1f0c', '\u1f04'), ('\u1f0d', '\u1f05'),
- ('\u1f0e', '\u1f06'), ('\u1f0f', '\u1f07'),
- ('\u1f18', '\u1f10'), ('\u1f19', '\u1f11'),
- ('\u1f1a', '\u1f12'), ('\u1f1b', '\u1f13'),
- ('\u1f1c', '\u1f14'), ('\u1f1d', '\u1f15'),
- ('\u1f28', '\u1f20'), ('\u1f29', '\u1f21'),
- ('\u1f2a', '\u1f22'), ('\u1f2b', '\u1f23'),
- ('\u1f2c', '\u1f24'), ('\u1f2d', '\u1f25'),
- ('\u1f2e', '\u1f26'), ('\u1f2f', '\u1f27'),
- ('\u1f38', '\u1f30'), ('\u1f39', '\u1f31'),
- ('\u1f3a', '\u1f32'), ('\u1f3b', '\u1f33'),
- ('\u1f3c', '\u1f34'), ('\u1f3d', '\u1f35'),
- ('\u1f3e', '\u1f36'), ('\u1f3f', '\u1f37'),
- ('\u1f48', '\u1f40'), ('\u1f49', '\u1f41'),
- ('\u1f4a', '\u1f42'), ('\u1f4b', '\u1f43'),
- ('\u1f4c', '\u1f44'), ('\u1f4d', '\u1f45'),
- ('\u1f59', '\u1f51'), ('\u1f5b', '\u1f53'),
- ('\u1f5d', '\u1f55'), ('\u1f5f', '\u1f57'),
- ('\u1f68', '\u1f60'), ('\u1f69', '\u1f61'),
- ('\u1f6a', '\u1f62'), ('\u1f6b', '\u1f63'),
- ('\u1f6c', '\u1f64'), ('\u1f6d', '\u1f65'),
- ('\u1f6e', '\u1f66'), ('\u1f6f', '\u1f67'),
- ('\u1fb8', '\u1fb0'), ('\u1fb9', '\u1fb1'),
- ('\u1fba', '\u1f70'), ('\u1fbb', '\u1f71'),
- ('\u1fc8', '\u1f72'), ('\u1fc9', '\u1f73'),
- ('\u1fca', '\u1f74'), ('\u1fcb', '\u1f75'),
- ('\u1fd8', '\u1fd0'), ('\u1fd9', '\u1fd1'),
- ('\u1fda', '\u1f76'), ('\u1fdb', '\u1f77'),
- ('\u1fe8', '\u1fe0'), ('\u1fe9', '\u1fe1'),
- ('\u1fea', '\u1f7a'), ('\u1feb', '\u1f7b'),
- ('\u1fec', '\u1fe5'), ('\u1ff8', '\u1f78'),
- ('\u1ff9', '\u1f79'), ('\u1ffa', '\u1f7c'),
- ('\u1ffb', '\u1f7d'), ('\u2126', '\u03c9'),
- ('\u212a', '\x6b'), ('\u212b', '\xe5'),
- ('\u2132', '\u214e'), ('\u2183', '\u2184'),
- ('\u2c00', '\u2c30'), ('\u2c01', '\u2c31'),
- ('\u2c02', '\u2c32'), ('\u2c03', '\u2c33'),
- ('\u2c04', '\u2c34'), ('\u2c05', '\u2c35'),
- ('\u2c06', '\u2c36'), ('\u2c07', '\u2c37'),
- ('\u2c08', '\u2c38'), ('\u2c09', '\u2c39'),
- ('\u2c0a', '\u2c3a'), ('\u2c0b', '\u2c3b'),
- ('\u2c0c', '\u2c3c'), ('\u2c0d', '\u2c3d'),
- ('\u2c0e', '\u2c3e'), ('\u2c0f', '\u2c3f'),
- ('\u2c10', '\u2c40'), ('\u2c11', '\u2c41'),
- ('\u2c12', '\u2c42'), ('\u2c13', '\u2c43'),
- ('\u2c14', '\u2c44'), ('\u2c15', '\u2c45'),
- ('\u2c16', '\u2c46'), ('\u2c17', '\u2c47'),
- ('\u2c18', '\u2c48'), ('\u2c19', '\u2c49'),
- ('\u2c1a', '\u2c4a'), ('\u2c1b', '\u2c4b'),
- ('\u2c1c', '\u2c4c'), ('\u2c1d', '\u2c4d'),
- ('\u2c1e', '\u2c4e'), ('\u2c1f', '\u2c4f'),
- ('\u2c20', '\u2c50'), ('\u2c21', '\u2c51'),
- ('\u2c22', '\u2c52'), ('\u2c23', '\u2c53'),
- ('\u2c24', '\u2c54'), ('\u2c25', '\u2c55'),
- ('\u2c26', '\u2c56'), ('\u2c27', '\u2c57'),
- ('\u2c28', '\u2c58'), ('\u2c29', '\u2c59'),
- ('\u2c2a', '\u2c5a'), ('\u2c2b', '\u2c5b'),
- ('\u2c2c', '\u2c5c'), ('\u2c2d', '\u2c5d'),
- ('\u2c2e', '\u2c5e'), ('\u2c60', '\u2c61'),
- ('\u2c62', '\u026b'), ('\u2c63', '\u1d7d'),
- ('\u2c64', '\u027d'), ('\u2c67', '\u2c68'),
- ('\u2c69', '\u2c6a'), ('\u2c6b', '\u2c6c'),
- ('\u2c6d', '\u0251'), ('\u2c6e', '\u0271'),
- ('\u2c6f', '\u0250'), ('\u2c70', '\u0252'),
- ('\u2c72', '\u2c73'), ('\u2c75', '\u2c76'),
- ('\u2c7e', '\u023f'), ('\u2c7f', '\u0240'),
- ('\u2c80', '\u2c81'), ('\u2c82', '\u2c83'),
- ('\u2c84', '\u2c85'), ('\u2c86', '\u2c87'),
- ('\u2c88', '\u2c89'), ('\u2c8a', '\u2c8b'),
- ('\u2c8c', '\u2c8d'), ('\u2c8e', '\u2c8f'),
- ('\u2c90', '\u2c91'), ('\u2c92', '\u2c93'),
- ('\u2c94', '\u2c95'), ('\u2c96', '\u2c97'),
- ('\u2c98', '\u2c99'), ('\u2c9a', '\u2c9b'),
- ('\u2c9c', '\u2c9d'), ('\u2c9e', '\u2c9f'),
- ('\u2ca0', '\u2ca1'), ('\u2ca2', '\u2ca3'),
- ('\u2ca4', '\u2ca5'), ('\u2ca6', '\u2ca7'),
- ('\u2ca8', '\u2ca9'), ('\u2caa', '\u2cab'),
- ('\u2cac', '\u2cad'), ('\u2cae', '\u2caf'),
- ('\u2cb0', '\u2cb1'), ('\u2cb2', '\u2cb3'),
- ('\u2cb4', '\u2cb5'), ('\u2cb6', '\u2cb7'),
- ('\u2cb8', '\u2cb9'), ('\u2cba', '\u2cbb'),
- ('\u2cbc', '\u2cbd'), ('\u2cbe', '\u2cbf'),
- ('\u2cc0', '\u2cc1'), ('\u2cc2', '\u2cc3'),
- ('\u2cc4', '\u2cc5'), ('\u2cc6', '\u2cc7'),
- ('\u2cc8', '\u2cc9'), ('\u2cca', '\u2ccb'),
- ('\u2ccc', '\u2ccd'), ('\u2cce', '\u2ccf'),
- ('\u2cd0', '\u2cd1'), ('\u2cd2', '\u2cd3'),
- ('\u2cd4', '\u2cd5'), ('\u2cd6', '\u2cd7'),
- ('\u2cd8', '\u2cd9'), ('\u2cda', '\u2cdb'),
- ('\u2cdc', '\u2cdd'), ('\u2cde', '\u2cdf'),
- ('\u2ce0', '\u2ce1'), ('\u2ce2', '\u2ce3'),
- ('\u2ceb', '\u2cec'), ('\u2ced', '\u2cee'),
- ('\u2cf2', '\u2cf3'), ('\ua640', '\ua641'),
- ('\ua642', '\ua643'), ('\ua644', '\ua645'),
- ('\ua646', '\ua647'), ('\ua648', '\ua649'),
- ('\ua64a', '\ua64b'), ('\ua64c', '\ua64d'),
- ('\ua64e', '\ua64f'), ('\ua650', '\ua651'),
- ('\ua652', '\ua653'), ('\ua654', '\ua655'),
- ('\ua656', '\ua657'), ('\ua658', '\ua659'),
- ('\ua65a', '\ua65b'), ('\ua65c', '\ua65d'),
- ('\ua65e', '\ua65f'), ('\ua660', '\ua661'),
- ('\ua662', '\ua663'), ('\ua664', '\ua665'),
- ('\ua666', '\ua667'), ('\ua668', '\ua669'),
- ('\ua66a', '\ua66b'), ('\ua66c', '\ua66d'),
- ('\ua680', '\ua681'), ('\ua682', '\ua683'),
- ('\ua684', '\ua685'), ('\ua686', '\ua687'),
- ('\ua688', '\ua689'), ('\ua68a', '\ua68b'),
- ('\ua68c', '\ua68d'), ('\ua68e', '\ua68f'),
- ('\ua690', '\ua691'), ('\ua692', '\ua693'),
- ('\ua694', '\ua695'), ('\ua696', '\ua697'),
- ('\ua722', '\ua723'), ('\ua724', '\ua725'),
- ('\ua726', '\ua727'), ('\ua728', '\ua729'),
- ('\ua72a', '\ua72b'), ('\ua72c', '\ua72d'),
- ('\ua72e', '\ua72f'), ('\ua732', '\ua733'),
- ('\ua734', '\ua735'), ('\ua736', '\ua737'),
- ('\ua738', '\ua739'), ('\ua73a', '\ua73b'),
- ('\ua73c', '\ua73d'), ('\ua73e', '\ua73f'),
- ('\ua740', '\ua741'), ('\ua742', '\ua743'),
- ('\ua744', '\ua745'), ('\ua746', '\ua747'),
- ('\ua748', '\ua749'), ('\ua74a', '\ua74b'),
- ('\ua74c', '\ua74d'), ('\ua74e', '\ua74f'),
- ('\ua750', '\ua751'), ('\ua752', '\ua753'),
- ('\ua754', '\ua755'), ('\ua756', '\ua757'),
- ('\ua758', '\ua759'), ('\ua75a', '\ua75b'),
- ('\ua75c', '\ua75d'), ('\ua75e', '\ua75f'),
- ('\ua760', '\ua761'), ('\ua762', '\ua763'),
- ('\ua764', '\ua765'), ('\ua766', '\ua767'),
- ('\ua768', '\ua769'), ('\ua76a', '\ua76b'),
- ('\ua76c', '\ua76d'), ('\ua76e', '\ua76f'),
- ('\ua779', '\ua77a'), ('\ua77b', '\ua77c'),
- ('\ua77d', '\u1d79'), ('\ua77e', '\ua77f'),
- ('\ua780', '\ua781'), ('\ua782', '\ua783'),
- ('\ua784', '\ua785'), ('\ua786', '\ua787'),
- ('\ua78b', '\ua78c'), ('\ua78d', '\u0265'),
- ('\ua790', '\ua791'), ('\ua792', '\ua793'),
- ('\ua7a0', '\ua7a1'), ('\ua7a2', '\ua7a3'),
- ('\ua7a4', '\ua7a5'), ('\ua7a6', '\ua7a7'),
- ('\ua7a8', '\ua7a9'), ('\ua7aa', '\u0266'),
- ('\uff21', '\uff41'), ('\uff22', '\uff42'),
- ('\uff23', '\uff43'), ('\uff24', '\uff44'),
- ('\uff25', '\uff45'), ('\uff26', '\uff46'),
- ('\uff27', '\uff47'), ('\uff28', '\uff48'),
- ('\uff29', '\uff49'), ('\uff2a', '\uff4a'),
- ('\uff2b', '\uff4b'), ('\uff2c', '\uff4c'),
- ('\uff2d', '\uff4d'), ('\uff2e', '\uff4e'),
- ('\uff2f', '\uff4f'), ('\uff30', '\uff50'),
- ('\uff31', '\uff51'), ('\uff32', '\uff52'),
- ('\uff33', '\uff53'), ('\uff34', '\uff54'),
- ('\uff35', '\uff55'), ('\uff36', '\uff56'),
- ('\uff37', '\uff57'), ('\uff38', '\uff58'),
- ('\uff39', '\uff59'), ('\uff3a', '\uff5a'),
- ('\U00010400', '\U00010428'), ('\U00010401', '\U00010429'),
- ('\U00010402', '\U0001042a'), ('\U00010403', '\U0001042b'),
- ('\U00010404', '\U0001042c'), ('\U00010405', '\U0001042d'),
- ('\U00010406', '\U0001042e'), ('\U00010407', '\U0001042f'),
- ('\U00010408', '\U00010430'), ('\U00010409', '\U00010431'),
- ('\U0001040a', '\U00010432'), ('\U0001040b', '\U00010433'),
- ('\U0001040c', '\U00010434'), ('\U0001040d', '\U00010435'),
- ('\U0001040e', '\U00010436'), ('\U0001040f', '\U00010437'),
- ('\U00010410', '\U00010438'), ('\U00010411', '\U00010439'),
- ('\U00010412', '\U0001043a'), ('\U00010413', '\U0001043b'),
- ('\U00010414', '\U0001043c'), ('\U00010415', '\U0001043d'),
- ('\U00010416', '\U0001043e'), ('\U00010417', '\U0001043f'),
- ('\U00010418', '\U00010440'), ('\U00010419', '\U00010441'),
- ('\U0001041a', '\U00010442'), ('\U0001041b', '\U00010443'),
- ('\U0001041c', '\U00010444'), ('\U0001041d', '\U00010445'),
- ('\U0001041e', '\U00010446'), ('\U0001041f', '\U00010447'),
- ('\U00010420', '\U00010448'), ('\U00010421', '\U00010449'),
- ('\U00010422', '\U0001044a'), ('\U00010423', '\U0001044b'),
- ('\U00010424', '\U0001044c'), ('\U00010425', '\U0001044d'),
- ('\U00010426', '\U0001044e'), ('\U00010427', '\U0001044f')
- ];
-
- static LlLu_table : &'static [(char, char)] = &[
- ('\x61', '\x41'), ('\x62', '\x42'),
- ('\x63', '\x43'), ('\x64', '\x44'),
- ('\x65', '\x45'), ('\x66', '\x46'),
- ('\x67', '\x47'), ('\x68', '\x48'),
- ('\x69', '\x49'), ('\x6a', '\x4a'),
- ('\x6b', '\x4b'), ('\x6c', '\x4c'),
- ('\x6d', '\x4d'), ('\x6e', '\x4e'),
- ('\x6f', '\x4f'), ('\x70', '\x50'),
- ('\x71', '\x51'), ('\x72', '\x52'),
- ('\x73', '\x53'), ('\x74', '\x54'),
- ('\x75', '\x55'), ('\x76', '\x56'),
- ('\x77', '\x57'), ('\x78', '\x58'),
- ('\x79', '\x59'), ('\x7a', '\x5a'),
- ('\xb5', '\u039c'), ('\xe0', '\xc0'),
- ('\xe1', '\xc1'), ('\xe2', '\xc2'),
- ('\xe3', '\xc3'), ('\xe4', '\xc4'),
- ('\xe5', '\xc5'), ('\xe6', '\xc6'),
- ('\xe7', '\xc7'), ('\xe8', '\xc8'),
- ('\xe9', '\xc9'), ('\xea', '\xca'),
- ('\xeb', '\xcb'), ('\xec', '\xcc'),
- ('\xed', '\xcd'), ('\xee', '\xce'),
- ('\xef', '\xcf'), ('\xf0', '\xd0'),
- ('\xf1', '\xd1'), ('\xf2', '\xd2'),
- ('\xf3', '\xd3'), ('\xf4', '\xd4'),
- ('\xf5', '\xd5'), ('\xf6', '\xd6'),
- ('\xf8', '\xd8'), ('\xf9', '\xd9'),
- ('\xfa', '\xda'), ('\xfb', '\xdb'),
- ('\xfc', '\xdc'), ('\xfd', '\xdd'),
- ('\xfe', '\xde'), ('\xff', '\u0178'),
- ('\u0101', '\u0100'), ('\u0103', '\u0102'),
- ('\u0105', '\u0104'), ('\u0107', '\u0106'),
- ('\u0109', '\u0108'), ('\u010b', '\u010a'),
- ('\u010d', '\u010c'), ('\u010f', '\u010e'),
- ('\u0111', '\u0110'), ('\u0113', '\u0112'),
- ('\u0115', '\u0114'), ('\u0117', '\u0116'),
- ('\u0119', '\u0118'), ('\u011b', '\u011a'),
- ('\u011d', '\u011c'), ('\u011f', '\u011e'),
- ('\u0121', '\u0120'), ('\u0123', '\u0122'),
- ('\u0125', '\u0124'), ('\u0127', '\u0126'),
- ('\u0129', '\u0128'), ('\u012b', '\u012a'),
- ('\u012d', '\u012c'), ('\u012f', '\u012e'),
- ('\u0131', '\x49'), ('\u0133', '\u0132'),
- ('\u0135', '\u0134'), ('\u0137', '\u0136'),
- ('\u013a', '\u0139'), ('\u013c', '\u013b'),
- ('\u013e', '\u013d'), ('\u0140', '\u013f'),
- ('\u0142', '\u0141'), ('\u0144', '\u0143'),
- ('\u0146', '\u0145'), ('\u0148', '\u0147'),
- ('\u014b', '\u014a'), ('\u014d', '\u014c'),
- ('\u014f', '\u014e'), ('\u0151', '\u0150'),
- ('\u0153', '\u0152'), ('\u0155', '\u0154'),
- ('\u0157', '\u0156'), ('\u0159', '\u0158'),
- ('\u015b', '\u015a'), ('\u015d', '\u015c'),
- ('\u015f', '\u015e'), ('\u0161', '\u0160'),
- ('\u0163', '\u0162'), ('\u0165', '\u0164'),
- ('\u0167', '\u0166'), ('\u0169', '\u0168'),
- ('\u016b', '\u016a'), ('\u016d', '\u016c'),
- ('\u016f', '\u016e'), ('\u0171', '\u0170'),
- ('\u0173', '\u0172'), ('\u0175', '\u0174'),
- ('\u0177', '\u0176'), ('\u017a', '\u0179'),
- ('\u017c', '\u017b'), ('\u017e', '\u017d'),
- ('\u017f', '\x53'), ('\u0180', '\u0243'),
- ('\u0183', '\u0182'), ('\u0185', '\u0184'),
- ('\u0188', '\u0187'), ('\u018c', '\u018b'),
- ('\u0192', '\u0191'), ('\u0195', '\u01f6'),
- ('\u0199', '\u0198'), ('\u019a', '\u023d'),
- ('\u019e', '\u0220'), ('\u01a1', '\u01a0'),
- ('\u01a3', '\u01a2'), ('\u01a5', '\u01a4'),
- ('\u01a8', '\u01a7'), ('\u01ad', '\u01ac'),
- ('\u01b0', '\u01af'), ('\u01b4', '\u01b3'),
- ('\u01b6', '\u01b5'), ('\u01b9', '\u01b8'),
- ('\u01bd', '\u01bc'), ('\u01bf', '\u01f7'),
- ('\u01c6', '\u01c4'), ('\u01c9', '\u01c7'),
- ('\u01cc', '\u01ca'), ('\u01ce', '\u01cd'),
- ('\u01d0', '\u01cf'), ('\u01d2', '\u01d1'),
- ('\u01d4', '\u01d3'), ('\u01d6', '\u01d5'),
- ('\u01d8', '\u01d7'), ('\u01da', '\u01d9'),
- ('\u01dc', '\u01db'), ('\u01dd', '\u018e'),
- ('\u01df', '\u01de'), ('\u01e1', '\u01e0'),
- ('\u01e3', '\u01e2'), ('\u01e5', '\u01e4'),
- ('\u01e7', '\u01e6'), ('\u01e9', '\u01e8'),
- ('\u01eb', '\u01ea'), ('\u01ed', '\u01ec'),
- ('\u01ef', '\u01ee'), ('\u01f3', '\u01f1'),
- ('\u01f5', '\u01f4'), ('\u01f9', '\u01f8'),
- ('\u01fb', '\u01fa'), ('\u01fd', '\u01fc'),
- ('\u01ff', '\u01fe'), ('\u0201', '\u0200'),
- ('\u0203', '\u0202'), ('\u0205', '\u0204'),
- ('\u0207', '\u0206'), ('\u0209', '\u0208'),
- ('\u020b', '\u020a'), ('\u020d', '\u020c'),
- ('\u020f', '\u020e'), ('\u0211', '\u0210'),
- ('\u0213', '\u0212'), ('\u0215', '\u0214'),
- ('\u0217', '\u0216'), ('\u0219', '\u0218'),
- ('\u021b', '\u021a'), ('\u021d', '\u021c'),
- ('\u021f', '\u021e'), ('\u0223', '\u0222'),
- ('\u0225', '\u0224'), ('\u0227', '\u0226'),
- ('\u0229', '\u0228'), ('\u022b', '\u022a'),
- ('\u022d', '\u022c'), ('\u022f', '\u022e'),
- ('\u0231', '\u0230'), ('\u0233', '\u0232'),
- ('\u023c', '\u023b'), ('\u023f', '\u2c7e'),
- ('\u0240', '\u2c7f'), ('\u0242', '\u0241'),
- ('\u0247', '\u0246'), ('\u0249', '\u0248'),
- ('\u024b', '\u024a'), ('\u024d', '\u024c'),
- ('\u024f', '\u024e'), ('\u0250', '\u2c6f'),
- ('\u0251', '\u2c6d'), ('\u0252', '\u2c70'),
- ('\u0253', '\u0181'), ('\u0254', '\u0186'),
- ('\u0256', '\u0189'), ('\u0257', '\u018a'),
- ('\u0259', '\u018f'), ('\u025b', '\u0190'),
- ('\u0260', '\u0193'), ('\u0263', '\u0194'),
- ('\u0265', '\ua78d'), ('\u0266', '\ua7aa'),
- ('\u0268', '\u0197'), ('\u0269', '\u0196'),
- ('\u026b', '\u2c62'), ('\u026f', '\u019c'),
- ('\u0271', '\u2c6e'), ('\u0272', '\u019d'),
- ('\u0275', '\u019f'), ('\u027d', '\u2c64'),
- ('\u0280', '\u01a6'), ('\u0283', '\u01a9'),
- ('\u0288', '\u01ae'), ('\u0289', '\u0244'),
- ('\u028a', '\u01b1'), ('\u028b', '\u01b2'),
- ('\u028c', '\u0245'), ('\u0292', '\u01b7'),
- ('\u0371', '\u0370'), ('\u0373', '\u0372'),
- ('\u0377', '\u0376'), ('\u037b', '\u03fd'),
- ('\u037c', '\u03fe'), ('\u037d', '\u03ff'),
- ('\u03ac', '\u0386'), ('\u03ad', '\u0388'),
- ('\u03ae', '\u0389'), ('\u03af', '\u038a'),
- ('\u03b1', '\u0391'), ('\u03b2', '\u0392'),
- ('\u03b3', '\u0393'), ('\u03b4', '\u0394'),
- ('\u03b5', '\u0395'), ('\u03b6', '\u0396'),
- ('\u03b7', '\u0397'), ('\u03b8', '\u0398'),
- ('\u03b9', '\u0399'), ('\u03ba', '\u039a'),
- ('\u03bb', '\u039b'), ('\u03bc', '\u039c'),
- ('\u03bd', '\u039d'), ('\u03be', '\u039e'),
- ('\u03bf', '\u039f'), ('\u03c0', '\u03a0'),
- ('\u03c1', '\u03a1'), ('\u03c2', '\u03a3'),
- ('\u03c3', '\u03a3'), ('\u03c4', '\u03a4'),
- ('\u03c5', '\u03a5'), ('\u03c6', '\u03a6'),
- ('\u03c7', '\u03a7'), ('\u03c8', '\u03a8'),
- ('\u03c9', '\u03a9'), ('\u03ca', '\u03aa'),
- ('\u03cb', '\u03ab'), ('\u03cc', '\u038c'),
- ('\u03cd', '\u038e'), ('\u03ce', '\u038f'),
- ('\u03d0', '\u0392'), ('\u03d1', '\u0398'),
- ('\u03d5', '\u03a6'), ('\u03d6', '\u03a0'),
- ('\u03d7', '\u03cf'), ('\u03d9', '\u03d8'),
- ('\u03db', '\u03da'), ('\u03dd', '\u03dc'),
- ('\u03df', '\u03de'), ('\u03e1', '\u03e0'),
- ('\u03e3', '\u03e2'), ('\u03e5', '\u03e4'),
- ('\u03e7', '\u03e6'), ('\u03e9', '\u03e8'),
- ('\u03eb', '\u03ea'), ('\u03ed', '\u03ec'),
- ('\u03ef', '\u03ee'), ('\u03f0', '\u039a'),
- ('\u03f1', '\u03a1'), ('\u03f2', '\u03f9'),
- ('\u03f5', '\u0395'), ('\u03f8', '\u03f7'),
- ('\u03fb', '\u03fa'), ('\u0430', '\u0410'),
- ('\u0431', '\u0411'), ('\u0432', '\u0412'),
- ('\u0433', '\u0413'), ('\u0434', '\u0414'),
- ('\u0435', '\u0415'), ('\u0436', '\u0416'),
- ('\u0437', '\u0417'), ('\u0438', '\u0418'),
- ('\u0439', '\u0419'), ('\u043a', '\u041a'),
- ('\u043b', '\u041b'), ('\u043c', '\u041c'),
- ('\u043d', '\u041d'), ('\u043e', '\u041e'),
- ('\u043f', '\u041f'), ('\u0440', '\u0420'),
- ('\u0441', '\u0421'), ('\u0442', '\u0422'),
- ('\u0443', '\u0423'), ('\u0444', '\u0424'),
- ('\u0445', '\u0425'), ('\u0446', '\u0426'),
- ('\u0447', '\u0427'), ('\u0448', '\u0428'),
- ('\u0449', '\u0429'), ('\u044a', '\u042a'),
- ('\u044b', '\u042b'), ('\u044c', '\u042c'),
- ('\u044d', '\u042d'), ('\u044e', '\u042e'),
- ('\u044f', '\u042f'), ('\u0450', '\u0400'),
- ('\u0451', '\u0401'), ('\u0452', '\u0402'),
- ('\u0453', '\u0403'), ('\u0454', '\u0404'),
- ('\u0455', '\u0405'), ('\u0456', '\u0406'),
- ('\u0457', '\u0407'), ('\u0458', '\u0408'),
- ('\u0459', '\u0409'), ('\u045a', '\u040a'),
- ('\u045b', '\u040b'), ('\u045c', '\u040c'),
- ('\u045d', '\u040d'), ('\u045e', '\u040e'),
- ('\u045f', '\u040f'), ('\u0461', '\u0460'),
- ('\u0463', '\u0462'), ('\u0465', '\u0464'),
- ('\u0467', '\u0466'), ('\u0469', '\u0468'),
- ('\u046b', '\u046a'), ('\u046d', '\u046c'),
- ('\u046f', '\u046e'), ('\u0471', '\u0470'),
- ('\u0473', '\u0472'), ('\u0475', '\u0474'),
- ('\u0477', '\u0476'), ('\u0479', '\u0478'),
- ('\u047b', '\u047a'), ('\u047d', '\u047c'),
- ('\u047f', '\u047e'), ('\u0481', '\u0480'),
- ('\u048b', '\u048a'), ('\u048d', '\u048c'),
- ('\u048f', '\u048e'), ('\u0491', '\u0490'),
- ('\u0493', '\u0492'), ('\u0495', '\u0494'),
- ('\u0497', '\u0496'), ('\u0499', '\u0498'),
- ('\u049b', '\u049a'), ('\u049d', '\u049c'),
- ('\u049f', '\u049e'), ('\u04a1', '\u04a0'),
- ('\u04a3', '\u04a2'), ('\u04a5', '\u04a4'),
- ('\u04a7', '\u04a6'), ('\u04a9', '\u04a8'),
- ('\u04ab', '\u04aa'), ('\u04ad', '\u04ac'),
- ('\u04af', '\u04ae'), ('\u04b1', '\u04b0'),
- ('\u04b3', '\u04b2'), ('\u04b5', '\u04b4'),
- ('\u04b7', '\u04b6'), ('\u04b9', '\u04b8'),
- ('\u04bb', '\u04ba'), ('\u04bd', '\u04bc'),
- ('\u04bf', '\u04be'), ('\u04c2', '\u04c1'),
- ('\u04c4', '\u04c3'), ('\u04c6', '\u04c5'),
- ('\u04c8', '\u04c7'), ('\u04ca', '\u04c9'),
- ('\u04cc', '\u04cb'), ('\u04ce', '\u04cd'),
- ('\u04cf', '\u04c0'), ('\u04d1', '\u04d0'),
- ('\u04d3', '\u04d2'), ('\u04d5', '\u04d4'),
- ('\u04d7', '\u04d6'), ('\u04d9', '\u04d8'),
- ('\u04db', '\u04da'), ('\u04dd', '\u04dc'),
- ('\u04df', '\u04de'), ('\u04e1', '\u04e0'),
- ('\u04e3', '\u04e2'), ('\u04e5', '\u04e4'),
- ('\u04e7', '\u04e6'), ('\u04e9', '\u04e8'),
- ('\u04eb', '\u04ea'), ('\u04ed', '\u04ec'),
- ('\u04ef', '\u04ee'), ('\u04f1', '\u04f0'),
- ('\u04f3', '\u04f2'), ('\u04f5', '\u04f4'),
- ('\u04f7', '\u04f6'), ('\u04f9', '\u04f8'),
- ('\u04fb', '\u04fa'), ('\u04fd', '\u04fc'),
- ('\u04ff', '\u04fe'), ('\u0501', '\u0500'),
- ('\u0503', '\u0502'), ('\u0505', '\u0504'),
- ('\u0507', '\u0506'), ('\u0509', '\u0508'),
- ('\u050b', '\u050a'), ('\u050d', '\u050c'),
- ('\u050f', '\u050e'), ('\u0511', '\u0510'),
- ('\u0513', '\u0512'), ('\u0515', '\u0514'),
- ('\u0517', '\u0516'), ('\u0519', '\u0518'),
- ('\u051b', '\u051a'), ('\u051d', '\u051c'),
- ('\u051f', '\u051e'), ('\u0521', '\u0520'),
- ('\u0523', '\u0522'), ('\u0525', '\u0524'),
- ('\u0527', '\u0526'), ('\u0561', '\u0531'),
- ('\u0562', '\u0532'), ('\u0563', '\u0533'),
- ('\u0564', '\u0534'), ('\u0565', '\u0535'),
- ('\u0566', '\u0536'), ('\u0567', '\u0537'),
- ('\u0568', '\u0538'), ('\u0569', '\u0539'),
- ('\u056a', '\u053a'), ('\u056b', '\u053b'),
- ('\u056c', '\u053c'), ('\u056d', '\u053d'),
- ('\u056e', '\u053e'), ('\u056f', '\u053f'),
- ('\u0570', '\u0540'), ('\u0571', '\u0541'),
- ('\u0572', '\u0542'), ('\u0573', '\u0543'),
- ('\u0574', '\u0544'), ('\u0575', '\u0545'),
- ('\u0576', '\u0546'), ('\u0577', '\u0547'),
- ('\u0578', '\u0548'), ('\u0579', '\u0549'),
- ('\u057a', '\u054a'), ('\u057b', '\u054b'),
- ('\u057c', '\u054c'), ('\u057d', '\u054d'),
- ('\u057e', '\u054e'), ('\u057f', '\u054f'),
- ('\u0580', '\u0550'), ('\u0581', '\u0551'),
- ('\u0582', '\u0552'), ('\u0583', '\u0553'),
- ('\u0584', '\u0554'), ('\u0585', '\u0555'),
- ('\u0586', '\u0556'), ('\u1d79', '\ua77d'),
- ('\u1d7d', '\u2c63'), ('\u1e01', '\u1e00'),
- ('\u1e03', '\u1e02'), ('\u1e05', '\u1e04'),
- ('\u1e07', '\u1e06'), ('\u1e09', '\u1e08'),
- ('\u1e0b', '\u1e0a'), ('\u1e0d', '\u1e0c'),
- ('\u1e0f', '\u1e0e'), ('\u1e11', '\u1e10'),
- ('\u1e13', '\u1e12'), ('\u1e15', '\u1e14'),
- ('\u1e17', '\u1e16'), ('\u1e19', '\u1e18'),
- ('\u1e1b', '\u1e1a'), ('\u1e1d', '\u1e1c'),
- ('\u1e1f', '\u1e1e'), ('\u1e21', '\u1e20'),
- ('\u1e23', '\u1e22'), ('\u1e25', '\u1e24'),
- ('\u1e27', '\u1e26'), ('\u1e29', '\u1e28'),
- ('\u1e2b', '\u1e2a'), ('\u1e2d', '\u1e2c'),
- ('\u1e2f', '\u1e2e'), ('\u1e31', '\u1e30'),
- ('\u1e33', '\u1e32'), ('\u1e35', '\u1e34'),
- ('\u1e37', '\u1e36'), ('\u1e39', '\u1e38'),
- ('\u1e3b', '\u1e3a'), ('\u1e3d', '\u1e3c'),
- ('\u1e3f', '\u1e3e'), ('\u1e41', '\u1e40'),
- ('\u1e43', '\u1e42'), ('\u1e45', '\u1e44'),
- ('\u1e47', '\u1e46'), ('\u1e49', '\u1e48'),
- ('\u1e4b', '\u1e4a'), ('\u1e4d', '\u1e4c'),
- ('\u1e4f', '\u1e4e'), ('\u1e51', '\u1e50'),
- ('\u1e53', '\u1e52'), ('\u1e55', '\u1e54'),
- ('\u1e57', '\u1e56'), ('\u1e59', '\u1e58'),
- ('\u1e5b', '\u1e5a'), ('\u1e5d', '\u1e5c'),
- ('\u1e5f', '\u1e5e'), ('\u1e61', '\u1e60'),
- ('\u1e63', '\u1e62'), ('\u1e65', '\u1e64'),
- ('\u1e67', '\u1e66'), ('\u1e69', '\u1e68'),
- ('\u1e6b', '\u1e6a'), ('\u1e6d', '\u1e6c'),
- ('\u1e6f', '\u1e6e'), ('\u1e71', '\u1e70'),
- ('\u1e73', '\u1e72'), ('\u1e75', '\u1e74'),
- ('\u1e77', '\u1e76'), ('\u1e79', '\u1e78'),
- ('\u1e7b', '\u1e7a'), ('\u1e7d', '\u1e7c'),
- ('\u1e7f', '\u1e7e'), ('\u1e81', '\u1e80'),
- ('\u1e83', '\u1e82'), ('\u1e85', '\u1e84'),
- ('\u1e87', '\u1e86'), ('\u1e89', '\u1e88'),
- ('\u1e8b', '\u1e8a'), ('\u1e8d', '\u1e8c'),
- ('\u1e8f', '\u1e8e'), ('\u1e91', '\u1e90'),
- ('\u1e93', '\u1e92'), ('\u1e95', '\u1e94'),
- ('\u1e9b', '\u1e60'), ('\u1ea1', '\u1ea0'),
- ('\u1ea3', '\u1ea2'), ('\u1ea5', '\u1ea4'),
- ('\u1ea7', '\u1ea6'), ('\u1ea9', '\u1ea8'),
- ('\u1eab', '\u1eaa'), ('\u1ead', '\u1eac'),
- ('\u1eaf', '\u1eae'), ('\u1eb1', '\u1eb0'),
- ('\u1eb3', '\u1eb2'), ('\u1eb5', '\u1eb4'),
- ('\u1eb7', '\u1eb6'), ('\u1eb9', '\u1eb8'),
- ('\u1ebb', '\u1eba'), ('\u1ebd', '\u1ebc'),
- ('\u1ebf', '\u1ebe'), ('\u1ec1', '\u1ec0'),
- ('\u1ec3', '\u1ec2'), ('\u1ec5', '\u1ec4'),
- ('\u1ec7', '\u1ec6'), ('\u1ec9', '\u1ec8'),
- ('\u1ecb', '\u1eca'), ('\u1ecd', '\u1ecc'),
- ('\u1ecf', '\u1ece'), ('\u1ed1', '\u1ed0'),
- ('\u1ed3', '\u1ed2'), ('\u1ed5', '\u1ed4'),
- ('\u1ed7', '\u1ed6'), ('\u1ed9', '\u1ed8'),
- ('\u1edb', '\u1eda'), ('\u1edd', '\u1edc'),
- ('\u1edf', '\u1ede'), ('\u1ee1', '\u1ee0'),
- ('\u1ee3', '\u1ee2'), ('\u1ee5', '\u1ee4'),
- ('\u1ee7', '\u1ee6'), ('\u1ee9', '\u1ee8'),
- ('\u1eeb', '\u1eea'), ('\u1eed', '\u1eec'),
- ('\u1eef', '\u1eee'), ('\u1ef1', '\u1ef0'),
- ('\u1ef3', '\u1ef2'), ('\u1ef5', '\u1ef4'),
- ('\u1ef7', '\u1ef6'), ('\u1ef9', '\u1ef8'),
- ('\u1efb', '\u1efa'), ('\u1efd', '\u1efc'),
- ('\u1eff', '\u1efe'), ('\u1f00', '\u1f08'),
- ('\u1f01', '\u1f09'), ('\u1f02', '\u1f0a'),
- ('\u1f03', '\u1f0b'), ('\u1f04', '\u1f0c'),
- ('\u1f05', '\u1f0d'), ('\u1f06', '\u1f0e'),
- ('\u1f07', '\u1f0f'), ('\u1f10', '\u1f18'),
- ('\u1f11', '\u1f19'), ('\u1f12', '\u1f1a'),
- ('\u1f13', '\u1f1b'), ('\u1f14', '\u1f1c'),
- ('\u1f15', '\u1f1d'), ('\u1f20', '\u1f28'),
- ('\u1f21', '\u1f29'), ('\u1f22', '\u1f2a'),
- ('\u1f23', '\u1f2b'), ('\u1f24', '\u1f2c'),
- ('\u1f25', '\u1f2d'), ('\u1f26', '\u1f2e'),
- ('\u1f27', '\u1f2f'), ('\u1f30', '\u1f38'),
- ('\u1f31', '\u1f39'), ('\u1f32', '\u1f3a'),
- ('\u1f33', '\u1f3b'), ('\u1f34', '\u1f3c'),
- ('\u1f35', '\u1f3d'), ('\u1f36', '\u1f3e'),
- ('\u1f37', '\u1f3f'), ('\u1f40', '\u1f48'),
- ('\u1f41', '\u1f49'), ('\u1f42', '\u1f4a'),
- ('\u1f43', '\u1f4b'), ('\u1f44', '\u1f4c'),
- ('\u1f45', '\u1f4d'), ('\u1f51', '\u1f59'),
- ('\u1f53', '\u1f5b'), ('\u1f55', '\u1f5d'),
- ('\u1f57', '\u1f5f'), ('\u1f60', '\u1f68'),
- ('\u1f61', '\u1f69'), ('\u1f62', '\u1f6a'),
- ('\u1f63', '\u1f6b'), ('\u1f64', '\u1f6c'),
- ('\u1f65', '\u1f6d'), ('\u1f66', '\u1f6e'),
- ('\u1f67', '\u1f6f'), ('\u1f70', '\u1fba'),
- ('\u1f71', '\u1fbb'), ('\u1f72', '\u1fc8'),
- ('\u1f73', '\u1fc9'), ('\u1f74', '\u1fca'),
- ('\u1f75', '\u1fcb'), ('\u1f76', '\u1fda'),
- ('\u1f77', '\u1fdb'), ('\u1f78', '\u1ff8'),
- ('\u1f79', '\u1ff9'), ('\u1f7a', '\u1fea'),
- ('\u1f7b', '\u1feb'), ('\u1f7c', '\u1ffa'),
- ('\u1f7d', '\u1ffb'), ('\u1f80', '\u1f88'),
- ('\u1f81', '\u1f89'), ('\u1f82', '\u1f8a'),
- ('\u1f83', '\u1f8b'), ('\u1f84', '\u1f8c'),
- ('\u1f85', '\u1f8d'), ('\u1f86', '\u1f8e'),
- ('\u1f87', '\u1f8f'), ('\u1f90', '\u1f98'),
- ('\u1f91', '\u1f99'), ('\u1f92', '\u1f9a'),
- ('\u1f93', '\u1f9b'), ('\u1f94', '\u1f9c'),
- ('\u1f95', '\u1f9d'), ('\u1f96', '\u1f9e'),
- ('\u1f97', '\u1f9f'), ('\u1fa0', '\u1fa8'),
- ('\u1fa1', '\u1fa9'), ('\u1fa2', '\u1faa'),
- ('\u1fa3', '\u1fab'), ('\u1fa4', '\u1fac'),
- ('\u1fa5', '\u1fad'), ('\u1fa6', '\u1fae'),
- ('\u1fa7', '\u1faf'), ('\u1fb0', '\u1fb8'),
- ('\u1fb1', '\u1fb9'), ('\u1fb3', '\u1fbc'),
- ('\u1fbe', '\u0399'), ('\u1fc3', '\u1fcc'),
- ('\u1fd0', '\u1fd8'), ('\u1fd1', '\u1fd9'),
- ('\u1fe0', '\u1fe8'), ('\u1fe1', '\u1fe9'),
- ('\u1fe5', '\u1fec'), ('\u1ff3', '\u1ffc'),
- ('\u214e', '\u2132'), ('\u2184', '\u2183'),
- ('\u2c30', '\u2c00'), ('\u2c31', '\u2c01'),
- ('\u2c32', '\u2c02'), ('\u2c33', '\u2c03'),
- ('\u2c34', '\u2c04'), ('\u2c35', '\u2c05'),
- ('\u2c36', '\u2c06'), ('\u2c37', '\u2c07'),
- ('\u2c38', '\u2c08'), ('\u2c39', '\u2c09'),
- ('\u2c3a', '\u2c0a'), ('\u2c3b', '\u2c0b'),
- ('\u2c3c', '\u2c0c'), ('\u2c3d', '\u2c0d'),
- ('\u2c3e', '\u2c0e'), ('\u2c3f', '\u2c0f'),
- ('\u2c40', '\u2c10'), ('\u2c41', '\u2c11'),
- ('\u2c42', '\u2c12'), ('\u2c43', '\u2c13'),
- ('\u2c44', '\u2c14'), ('\u2c45', '\u2c15'),
- ('\u2c46', '\u2c16'), ('\u2c47', '\u2c17'),
- ('\u2c48', '\u2c18'), ('\u2c49', '\u2c19'),
- ('\u2c4a', '\u2c1a'), ('\u2c4b', '\u2c1b'),
- ('\u2c4c', '\u2c1c'), ('\u2c4d', '\u2c1d'),
- ('\u2c4e', '\u2c1e'), ('\u2c4f', '\u2c1f'),
- ('\u2c50', '\u2c20'), ('\u2c51', '\u2c21'),
- ('\u2c52', '\u2c22'), ('\u2c53', '\u2c23'),
- ('\u2c54', '\u2c24'), ('\u2c55', '\u2c25'),
- ('\u2c56', '\u2c26'), ('\u2c57', '\u2c27'),
- ('\u2c58', '\u2c28'), ('\u2c59', '\u2c29'),
- ('\u2c5a', '\u2c2a'), ('\u2c5b', '\u2c2b'),
- ('\u2c5c', '\u2c2c'), ('\u2c5d', '\u2c2d'),
- ('\u2c5e', '\u2c2e'), ('\u2c61', '\u2c60'),
- ('\u2c65', '\u023a'), ('\u2c66', '\u023e'),
- ('\u2c68', '\u2c67'), ('\u2c6a', '\u2c69'),
- ('\u2c6c', '\u2c6b'), ('\u2c73', '\u2c72'),
- ('\u2c76', '\u2c75'), ('\u2c81', '\u2c80'),
- ('\u2c83', '\u2c82'), ('\u2c85', '\u2c84'),
- ('\u2c87', '\u2c86'), ('\u2c89', '\u2c88'),
- ('\u2c8b', '\u2c8a'), ('\u2c8d', '\u2c8c'),
- ('\u2c8f', '\u2c8e'), ('\u2c91', '\u2c90'),
- ('\u2c93', '\u2c92'), ('\u2c95', '\u2c94'),
- ('\u2c97', '\u2c96'), ('\u2c99', '\u2c98'),
- ('\u2c9b', '\u2c9a'), ('\u2c9d', '\u2c9c'),
- ('\u2c9f', '\u2c9e'), ('\u2ca1', '\u2ca0'),
- ('\u2ca3', '\u2ca2'), ('\u2ca5', '\u2ca4'),
- ('\u2ca7', '\u2ca6'), ('\u2ca9', '\u2ca8'),
- ('\u2cab', '\u2caa'), ('\u2cad', '\u2cac'),
- ('\u2caf', '\u2cae'), ('\u2cb1', '\u2cb0'),
- ('\u2cb3', '\u2cb2'), ('\u2cb5', '\u2cb4'),
- ('\u2cb7', '\u2cb6'), ('\u2cb9', '\u2cb8'),
- ('\u2cbb', '\u2cba'), ('\u2cbd', '\u2cbc'),
- ('\u2cbf', '\u2cbe'), ('\u2cc1', '\u2cc0'),
- ('\u2cc3', '\u2cc2'), ('\u2cc5', '\u2cc4'),
- ('\u2cc7', '\u2cc6'), ('\u2cc9', '\u2cc8'),
- ('\u2ccb', '\u2cca'), ('\u2ccd', '\u2ccc'),
- ('\u2ccf', '\u2cce'), ('\u2cd1', '\u2cd0'),
- ('\u2cd3', '\u2cd2'), ('\u2cd5', '\u2cd4'),
- ('\u2cd7', '\u2cd6'), ('\u2cd9', '\u2cd8'),
- ('\u2cdb', '\u2cda'), ('\u2cdd', '\u2cdc'),
- ('\u2cdf', '\u2cde'), ('\u2ce1', '\u2ce0'),
- ('\u2ce3', '\u2ce2'), ('\u2cec', '\u2ceb'),
- ('\u2cee', '\u2ced'), ('\u2cf3', '\u2cf2'),
- ('\u2d00', '\u10a0'), ('\u2d01', '\u10a1'),
- ('\u2d02', '\u10a2'), ('\u2d03', '\u10a3'),
- ('\u2d04', '\u10a4'), ('\u2d05', '\u10a5'),
- ('\u2d06', '\u10a6'), ('\u2d07', '\u10a7'),
- ('\u2d08', '\u10a8'), ('\u2d09', '\u10a9'),
- ('\u2d0a', '\u10aa'), ('\u2d0b', '\u10ab'),
- ('\u2d0c', '\u10ac'), ('\u2d0d', '\u10ad'),
- ('\u2d0e', '\u10ae'), ('\u2d0f', '\u10af'),
- ('\u2d10', '\u10b0'), ('\u2d11', '\u10b1'),
- ('\u2d12', '\u10b2'), ('\u2d13', '\u10b3'),
- ('\u2d14', '\u10b4'), ('\u2d15', '\u10b5'),
- ('\u2d16', '\u10b6'), ('\u2d17', '\u10b7'),
- ('\u2d18', '\u10b8'), ('\u2d19', '\u10b9'),
- ('\u2d1a', '\u10ba'), ('\u2d1b', '\u10bb'),
- ('\u2d1c', '\u10bc'), ('\u2d1d', '\u10bd'),
- ('\u2d1e', '\u10be'), ('\u2d1f', '\u10bf'),
- ('\u2d20', '\u10c0'), ('\u2d21', '\u10c1'),
- ('\u2d22', '\u10c2'), ('\u2d23', '\u10c3'),
- ('\u2d24', '\u10c4'), ('\u2d25', '\u10c5'),
- ('\u2d27', '\u10c7'), ('\u2d2d', '\u10cd'),
- ('\ua641', '\ua640'), ('\ua643', '\ua642'),
- ('\ua645', '\ua644'), ('\ua647', '\ua646'),
- ('\ua649', '\ua648'), ('\ua64b', '\ua64a'),
- ('\ua64d', '\ua64c'), ('\ua64f', '\ua64e'),
- ('\ua651', '\ua650'), ('\ua653', '\ua652'),
- ('\ua655', '\ua654'), ('\ua657', '\ua656'),
- ('\ua659', '\ua658'), ('\ua65b', '\ua65a'),
- ('\ua65d', '\ua65c'), ('\ua65f', '\ua65e'),
- ('\ua661', '\ua660'), ('\ua663', '\ua662'),
- ('\ua665', '\ua664'), ('\ua667', '\ua666'),
- ('\ua669', '\ua668'), ('\ua66b', '\ua66a'),
- ('\ua66d', '\ua66c'), ('\ua681', '\ua680'),
- ('\ua683', '\ua682'), ('\ua685', '\ua684'),
- ('\ua687', '\ua686'), ('\ua689', '\ua688'),
- ('\ua68b', '\ua68a'), ('\ua68d', '\ua68c'),
- ('\ua68f', '\ua68e'), ('\ua691', '\ua690'),
- ('\ua693', '\ua692'), ('\ua695', '\ua694'),
- ('\ua697', '\ua696'), ('\ua723', '\ua722'),
- ('\ua725', '\ua724'), ('\ua727', '\ua726'),
- ('\ua729', '\ua728'), ('\ua72b', '\ua72a'),
- ('\ua72d', '\ua72c'), ('\ua72f', '\ua72e'),
- ('\ua733', '\ua732'), ('\ua735', '\ua734'),
- ('\ua737', '\ua736'), ('\ua739', '\ua738'),
- ('\ua73b', '\ua73a'), ('\ua73d', '\ua73c'),
- ('\ua73f', '\ua73e'), ('\ua741', '\ua740'),
- ('\ua743', '\ua742'), ('\ua745', '\ua744'),
- ('\ua747', '\ua746'), ('\ua749', '\ua748'),
- ('\ua74b', '\ua74a'), ('\ua74d', '\ua74c'),
- ('\ua74f', '\ua74e'), ('\ua751', '\ua750'),
- ('\ua753', '\ua752'), ('\ua755', '\ua754'),
- ('\ua757', '\ua756'), ('\ua759', '\ua758'),
- ('\ua75b', '\ua75a'), ('\ua75d', '\ua75c'),
- ('\ua75f', '\ua75e'), ('\ua761', '\ua760'),
- ('\ua763', '\ua762'), ('\ua765', '\ua764'),
- ('\ua767', '\ua766'), ('\ua769', '\ua768'),
- ('\ua76b', '\ua76a'), ('\ua76d', '\ua76c'),
- ('\ua76f', '\ua76e'), ('\ua77a', '\ua779'),
- ('\ua77c', '\ua77b'), ('\ua77f', '\ua77e'),
- ('\ua781', '\ua780'), ('\ua783', '\ua782'),
- ('\ua785', '\ua784'), ('\ua787', '\ua786'),
- ('\ua78c', '\ua78b'), ('\ua791', '\ua790'),
- ('\ua793', '\ua792'), ('\ua7a1', '\ua7a0'),
- ('\ua7a3', '\ua7a2'), ('\ua7a5', '\ua7a4'),
- ('\ua7a7', '\ua7a6'), ('\ua7a9', '\ua7a8'),
- ('\uff41', '\uff21'), ('\uff42', '\uff22'),
- ('\uff43', '\uff23'), ('\uff44', '\uff24'),
- ('\uff45', '\uff25'), ('\uff46', '\uff26'),
- ('\uff47', '\uff27'), ('\uff48', '\uff28'),
- ('\uff49', '\uff29'), ('\uff4a', '\uff2a'),
- ('\uff4b', '\uff2b'), ('\uff4c', '\uff2c'),
- ('\uff4d', '\uff2d'), ('\uff4e', '\uff2e'),
- ('\uff4f', '\uff2f'), ('\uff50', '\uff30'),
- ('\uff51', '\uff31'), ('\uff52', '\uff32'),
- ('\uff53', '\uff33'), ('\uff54', '\uff34'),
- ('\uff55', '\uff35'), ('\uff56', '\uff36'),
- ('\uff57', '\uff37'), ('\uff58', '\uff38'),
- ('\uff59', '\uff39'), ('\uff5a', '\uff3a'),
- ('\U00010428', '\U00010400'), ('\U00010429', '\U00010401'),
- ('\U0001042a', '\U00010402'), ('\U0001042b', '\U00010403'),
- ('\U0001042c', '\U00010404'), ('\U0001042d', '\U00010405'),
- ('\U0001042e', '\U00010406'), ('\U0001042f', '\U00010407'),
- ('\U00010430', '\U00010408'), ('\U00010431', '\U00010409'),
- ('\U00010432', '\U0001040a'), ('\U00010433', '\U0001040b'),
- ('\U00010434', '\U0001040c'), ('\U00010435', '\U0001040d'),
- ('\U00010436', '\U0001040e'), ('\U00010437', '\U0001040f'),
- ('\U00010438', '\U00010410'), ('\U00010439', '\U00010411'),
- ('\U0001043a', '\U00010412'), ('\U0001043b', '\U00010413'),
- ('\U0001043c', '\U00010414'), ('\U0001043d', '\U00010415'),
- ('\U0001043e', '\U00010416'), ('\U0001043f', '\U00010417'),
- ('\U00010440', '\U00010418'), ('\U00010441', '\U00010419'),
- ('\U00010442', '\U0001041a'), ('\U00010443', '\U0001041b'),
- ('\U00010444', '\U0001041c'), ('\U00010445', '\U0001041d'),
- ('\U00010446', '\U0001041e'), ('\U00010447', '\U0001041f'),
- ('\U00010448', '\U00010420'), ('\U00010449', '\U00010421'),
- ('\U0001044a', '\U00010422'), ('\U0001044b', '\U00010423'),
- ('\U0001044c', '\U00010424'), ('\U0001044d', '\U00010425'),
- ('\U0001044e', '\U00010426'), ('\U0001044f', '\U00010427')
- ];
-
-}
assert_eq!(s.as_slice(), "\\U0001d4b6");
}
-#[test]
-fn test_to_str() {
- let s = 't'.to_str();
- assert_eq!(s.as_slice(), "t");
-}
-
#[test]
fn test_encode_utf8() {
fn check(input: char, expect: &[u8]) {
check('\ua66e', [0xa66e]);
check('\U0001f4a9', [0xd83d, 0xdca9]);
}
+
+#[test]
+fn test_width() {
+ assert_eq!('\x00'.width(false),Some(0));
+ assert_eq!('\x00'.width(true),Some(0));
+
+ assert_eq!('\x0A'.width(false),None);
+ assert_eq!('\x0A'.width(true),None);
+
+ assert_eq!('w'.width(false),Some(1));
+ assert_eq!('w'.width(true),Some(1));
+
+ assert_eq!('h'.width(false),Some(2));
+ assert_eq!('h'.width(true),Some(2));
+
+ assert_eq!('\xAD'.width(false),Some(1));
+ assert_eq!('\xAD'.width(true),Some(1));
+
+ assert_eq!('\u1160'.width(false),Some(0));
+ assert_eq!('\u1160'.width(true),Some(0));
+
+ assert_eq!('\u00a1'.width(false),Some(1));
+ assert_eq!('\u00a1'.width(true),Some(2));
+
+ assert_eq!('\u0300'.width(false),Some(0));
+ assert_eq!('\u0300'.width(true),Some(0));
+}
let r = MinMax(1i,2);
assert_eq!(r.into_option(), Some((1,2)));
}
+
+#[test]
+fn test_iterate() {
+ let mut it = iterate(|x| x * 2, 1u);
+ assert_eq!(it.next(), Some(1u));
+ assert_eq!(it.next(), Some(2u));
+ assert_eq!(it.next(), Some(4u));
+ assert_eq!(it.next(), Some(8u));
+}
// If we have a specified width for formatting, then we have to make
// this allocation of a new string
_ => {
- let s = repr::repr_to_str(self);
+ let s = repr::repr_to_string(self);
f.pad(s.as_slice())
}
}
//! Additionally, it is not guaranteed that functionality such as reflection
//! will persist into the future.
-#![crate_id = "debug#0.11.0"]
+#![crate_name = "debug"]
#![experimental]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+ html_root_url = "http://doc.rust-lang.org/master/")]
#![experimental]
#![feature(managed_boxes, macro_rules)]
#![allow(experimental)]
macro_rules! num_repr(($ty:ident, $suffix:expr) => (impl Repr for $ty {
fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
- let s = self.to_str();
+ let s = self.to_string();
writer.write(s.as_bytes()).and_then(|()| {
writer.write($suffix)
})
}
}
-pub fn repr_to_str<T>(t: &T) -> String {
+pub fn repr_to_string<T>(t: &T) -> String {
let mut result = io::MemWriter::new();
write_repr(&mut result as &mut io::Writer, t).unwrap();
String::from_utf8(result.unwrap()).unwrap()
*/
-#![crate_id = "flate#0.11.0"]
+#![crate_name = "flate"]
#![experimental]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+ html_root_url = "http://doc.rust-lang.org/master/")]
#![feature(phase)]
#[cfg(test)] #[phase(plugin, link)] extern crate log;
//! Parsing does not happen at runtime: structures of `std::fmt::rt` are
//! generated instead.
-#![crate_id = "fmt_macros#0.11.0"]
+#![crate_name = "fmt_macros"]
#![experimental]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
*/
-#![crate_id = "fourcc#0.11.0"]
+#![crate_name = "fourcc"]
#![experimental]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+ html_root_url = "http://doc.rust-lang.org/master/")]
#![feature(plugin_registrar, managed_boxes)]
//! ];
//! let matches = match getopts(args.tail(), opts) {
//! Ok(m) => { m }
-//! Err(f) => { fail!(f.to_str()) }
+//! Err(f) => { fail!(f.to_string()) }
//! };
//! if matches.opt_present("h") {
//! print_usage(program.as_slice(), opts);
//! }
//! ~~~
-#![crate_id = "getopts#0.11.0"]
+#![crate_name = "getopts"]
#![experimental]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
#![feature(globs, phase)]
#![deny(missing_doc)]
}
}
- fn to_str(&self) -> String {
+ fn to_string(&self) -> String {
match *self {
- Short(ch) => ch.to_str(),
+ Short(ch) => ch.to_string(),
Long(ref s) => s.to_string()
}
}
/// Convert a `Fail_` enum into an error string.
#[deprecated="use `Show` (`{}` format specifier)"]
pub fn to_err_msg(self) -> String {
- self.to_str()
+ self.to_string()
}
}
name_pos += 1;
let optid = match find_opt(opts.as_slice(), (*nm).clone()) {
Some(id) => id,
- None => return Err(UnrecognizedOption(nm.to_str()))
+ None => return Err(UnrecognizedOption(nm.to_string()))
};
match opts.get(optid).hasarg {
No => {
if !i_arg.is_none() {
- return Err(UnexpectedArgument(nm.to_str()));
+ return Err(UnexpectedArgument(nm.to_string()));
}
vals.get_mut(optid).push(Given);
}
if !i_arg.is_none() {
vals.get_mut(optid).push(Val(i_arg.clone().unwrap()));
} else if i + 1 == l {
- return Err(ArgumentMissing(nm.to_str()));
+ return Err(ArgumentMissing(nm.to_string()));
} else {
i += 1;
vals.get_mut(optid).push(Val(args[i].clone()));
let occ = opts.get(i).occur;
if occ == Req {
if n == 0 {
- return Err(OptionMissing(opts.get(i).name.to_str()));
+ return Err(OptionMissing(opts.get(i).name.to_string()));
}
}
if occ != Multi {
if n > 1 {
- return Err(OptionDuplicated(opts.get(i).name.to_str()));
+ return Err(OptionDuplicated(opts.get(i).name.to_string()));
}
}
i += 1;
*cont
};
- ss.char_indices().advance(|x| machine(&mut cont, x));
+ ss.char_indices().all(|x| machine(&mut cont, x));
// Let the automaton 'run out' by supplying trailing whitespace
while cont && match state { B | C => true, A => false } {
* `glob`/`fnmatch` functions.
*/
-#![crate_id = "glob#0.11.0"]
+#![crate_name = "glob"]
#![experimental]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
use std::cell::Cell;
* currently only considers upper/lower case relationships between ASCII characters,
* but in future this might be extended to work with Unicode.
*/
- case_sensitive: bool,
+ pub case_sensitive: bool,
/**
* If this is true then path-component separator characters (e.g. `/` on Posix)
* must be matched by a literal `/`, rather than by `*` or `?` or `[...]`
*/
- require_literal_separator: bool,
+ pub require_literal_separator: bool,
/**
* If this is true then paths that contain components that start with a `.` will
* will not match. This is useful because such files are conventionally considered
* hidden on Unix systems and it might be desirable to skip them when listing files.
*/
- require_literal_leading_dot: bool
+ pub require_literal_leading_dot: bool
}
impl MatchOptions {
for &p in pats.iter() {
let pat = Pattern::new(p);
for c in "abcdefghijklmnopqrstuvwxyz".chars() {
- assert!(pat.matches(c.to_str().as_slice()));
+ assert!(pat.matches(c.to_string().as_slice()));
}
for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ".chars() {
let options = MatchOptions {case_sensitive: false, .. MatchOptions::new()};
- assert!(pat.matches_with(c.to_str().as_slice(), options));
+ assert!(pat.matches_with(c.to_string().as_slice(), options));
}
assert!(pat.matches("1"));
assert!(pat.matches("2"));
*/
-#![crate_id = "graphviz#0.11.0"]
+#![crate_name = "graphviz"]
#![experimental]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/")]
-
-#![experimental]
+ html_root_url = "http://doc.rust-lang.org/master/")]
use std::io;
use std::str;
/// Renders text as string suitable for a label in a .dot file.
pub fn escape(&self) -> String {
match self {
- &LabelStr(ref s) => s.as_slice().escape_default().to_string(),
- &EscStr(ref s) => LabelText::escape_str(s.as_slice()).to_string(),
+ &LabelStr(ref s) => s.as_slice().escape_default(),
+ &EscStr(ref s) => LabelText::escape_str(s.as_slice()),
+ }
+ }
+
+ /// Decomposes content into string suitable for making EscStr that
+ /// yields same content as self. The result obeys the law
+ /// render(`lt`) == render(`EscStr(lt.pre_escaped_content())`) for
+ /// all `lt: LabelText`.
+ fn pre_escaped_content(self) -> str::MaybeOwned<'a> {
+ match self {
+ EscStr(s) => s,
+ LabelStr(s) => if s.as_slice().contains_char('\\') {
+ str::Owned(s.as_slice().escape_default())
+ } else {
+ s
+ },
}
}
+
+ /// Puts `prefix` on a line above this label, with a blank line separator.
+ pub fn prefix_line(self, prefix: LabelText) -> LabelText {
+ prefix.suffix_line(self)
+ }
+
+ /// Puts `suffix` on a line below this label, with a blank line separator.
+ pub fn suffix_line(self, suffix: LabelText) -> LabelText {
+ let prefix = self.pre_escaped_content().into_string();
+ let suffix = suffix.pre_escaped_content();
+ EscStr(str::Owned(prefix.append(r"\n\n").append(suffix.as_slice())))
+ }
}
pub type Nodes<'a,N> = MaybeOwnedVector<'a,N>;
let mut writer = MemWriter::new();
render(&g, &mut writer).unwrap();
let mut r = BufReader::new(writer.get_ref());
- match r.read_to_str() {
- Ok(string) => Ok(string.to_string()),
- Err(err) => Err(err),
- }
+ r.read_to_string()
}
// All of the tests use raw-strings as the format for the expected outputs,
render(&g, &mut writer).unwrap();
let mut r = BufReader::new(writer.get_ref());
- let r = r.read_to_str();
+ let r = r.read_to_string();
assert_eq!(r.unwrap().as_slice(),
r#"digraph syntax_tree {
//! possibly pinned to a particular scheduler thread:
//!
//! ```rust
+//! extern crate green;
+//! extern crate rustuv;
+//!
+//! # fn main() {
//! use std::task::TaskBuilder;
//! use green::{SchedPool, PoolConfig, GreenTaskBuilder};
//!
-//! let config = PoolConfig::new();
+//! let mut config = PoolConfig::new();
+//!
+//! // Optional: Set the event loop to be rustuv's to allow I/O to work
+//! config.event_loop_factory = rustuv::event_loop;
+//!
//! let mut pool = SchedPool::new(config);
//!
//! // Spawn tasks into the pool of schedulers
//! // Required to shut down this scheduler pool.
//! // The task will fail if `shutdown` is not called.
//! pool.shutdown();
+//! # }
//! ```
-#![crate_id = "green#0.11.0"]
+#![crate_name = "green"]
#![experimental]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
// NB this does *not* include globs, please keep it that way.
-#![feature(macro_rules, phase)]
-#![allow(visible_private_types)]
-#![allow(deprecated)]
-#![feature(default_type_params)]
+#![feature(macro_rules, phase, default_type_params)]
+#![allow(visible_private_types, deprecated)]
#[cfg(test)] #[phase(plugin, link)] extern crate log;
#[cfg(test)] extern crate rustuv;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+use std::ptr;
use std::sync::atomics;
use std::os::{errno, page_size, MemoryMap, MapReadable, MapWritable,
- MapNonStandardFlags, MapVirtual, getenv};
+ MapNonStandardFlags, getenv};
use libc;
/// A task's stack. The name "Stack" is a vestige of segmented stacks.
pub struct Stack {
- buf: MemoryMap,
+ buf: Option<MemoryMap>,
min_size: uint,
valgrind_id: libc::c_uint,
}
// guaranteed to be aligned properly.
if !protect_last_page(&stack) {
fail!("Could not memory-protect guard page. stack={}, errno={}",
- stack.data, errno());
+ stack.data(), errno());
}
let mut stk = Stack {
- buf: stack,
+ buf: Some(stack),
min_size: size,
valgrind_id: 0
};
/// Create a 0-length stack which starts (and ends) at 0.
pub unsafe fn dummy_stack() -> Stack {
Stack {
- buf: MemoryMap { data: 0 as *mut u8, len: 0, kind: MapVirtual },
+ buf: None,
min_size: 0,
valgrind_id: 0
}
/// Point to the low end of the allocated stack
pub fn start(&self) -> *const uint {
- self.buf.data as *const uint
+ self.buf.as_ref().map(|m| m.data() as *const uint)
+ .unwrap_or(ptr::null())
}
/// Point one uint beyond the high end of the allocated stack
pub fn end(&self) -> *const uint {
- unsafe {
- self.buf.data.offset(self.buf.len as int) as *const uint
- }
+ self.buf.as_ref().map(|buf| unsafe {
+ buf.data().offset(buf.len() as int) as *const uint
+ }).unwrap_or(ptr::null())
}
}
// This may seem backwards: the start of the segment is the last page?
// Yes! The stack grows from higher addresses (the end of the allocated
// block) to lower addresses (the start of the allocated block).
- let last_page = stack.data as *mut libc::c_void;
+ let last_page = stack.data() as *mut libc::c_void;
libc::mprotect(last_page, page_size() as libc::size_t,
libc::PROT_NONE) != -1
}
fn protect_last_page(stack: &MemoryMap) -> bool {
unsafe {
// see above
- let last_page = stack.data as *mut libc::c_void;
+ let last_page = stack.data() as *mut libc::c_void;
let mut old_prot: libc::DWORD = 0;
libc::VirtualProtect(last_page, page_size() as libc::SIZE_T,
libc::PAGE_NOACCESS,
*/
-#![crate_id = "hexfloat#0.11.0"]
+#![crate_name = "hexfloat"]
#![experimental]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+ html_root_url = "http://doc.rust-lang.org/master/")]
#![feature(plugin_registrar, managed_boxes)]
extern crate syntax;
// except according to those terms.
#![feature(globs)]
-#![crate_id = "libc#0.11.0"]
+#![crate_name = "libc"]
#![experimental]
#![no_std] // we don't need std, and we can't have std, since it doesn't exist
// yet. std depends on us.
#![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
/*!
pub mod posix88 {
use types::os::arch::c95::c_int;
use types::common::c95::c_void;
+ use types::os::arch::posix88::mode_t;
pub static O_RDONLY : c_int = 0;
pub static O_WRONLY : c_int = 1;
pub static O_CREAT : c_int = 64;
pub static O_EXCL : c_int = 128;
pub static O_TRUNC : c_int = 512;
- pub static S_IFIFO : c_int = 4096;
- pub static S_IFCHR : c_int = 8192;
- pub static S_IFBLK : c_int = 24576;
- pub static S_IFDIR : c_int = 16384;
- pub static S_IFREG : c_int = 32768;
- pub static S_IFLNK : c_int = 40960;
- pub static S_IFMT : c_int = 61440;
- pub static S_IEXEC : c_int = 64;
- pub static S_IWRITE : c_int = 128;
- pub static S_IREAD : c_int = 256;
- pub static S_IRWXU : c_int = 448;
- pub static S_IXUSR : c_int = 64;
- pub static S_IWUSR : c_int = 128;
- pub static S_IRUSR : c_int = 256;
+ pub static S_IFIFO : mode_t = 4096;
+ pub static S_IFCHR : mode_t = 8192;
+ pub static S_IFBLK : mode_t = 24576;
+ pub static S_IFDIR : mode_t = 16384;
+ pub static S_IFREG : mode_t = 32768;
+ pub static S_IFLNK : mode_t = 40960;
+ pub static S_IFMT : mode_t = 61440;
+ pub static S_IEXEC : mode_t = 64;
+ pub static S_IWRITE : mode_t = 128;
+ pub static S_IREAD : mode_t = 256;
+ pub static S_IRWXU : mode_t = 448;
+ pub static S_IXUSR : mode_t = 64;
+ pub static S_IWUSR : mode_t = 128;
+ pub static S_IRUSR : mode_t = 256;
pub static F_OK : c_int = 0;
pub static R_OK : c_int = 4;
pub static W_OK : c_int = 2;
pub mod posix88 {
use types::os::arch::c95::c_int;
use types::common::c95::c_void;
+ use types::os::arch::posix88::mode_t;
pub static O_RDONLY : c_int = 0;
pub static O_WRONLY : c_int = 1;
pub static O_CREAT : c_int = 256;
pub static O_EXCL : c_int = 1024;
pub static O_TRUNC : c_int = 512;
- pub static S_IFIFO : c_int = 4096;
- pub static S_IFCHR : c_int = 8192;
- pub static S_IFBLK : c_int = 24576;
- pub static S_IFDIR : c_int = 16384;
- pub static S_IFREG : c_int = 32768;
- pub static S_IFLNK : c_int = 40960;
- pub static S_IFMT : c_int = 61440;
- pub static S_IEXEC : c_int = 64;
- pub static S_IWRITE : c_int = 128;
- pub static S_IREAD : c_int = 256;
- pub static S_IRWXU : c_int = 448;
- pub static S_IXUSR : c_int = 64;
- pub static S_IWUSR : c_int = 128;
- pub static S_IRUSR : c_int = 256;
+ pub static S_IFIFO : mode_t = 4096;
+ pub static S_IFCHR : mode_t = 8192;
+ pub static S_IFBLK : mode_t = 24576;
+ pub static S_IFDIR : mode_t = 16384;
+ pub static S_IFREG : mode_t = 32768;
+ pub static S_IFLNK : mode_t = 40960;
+ pub static S_IFMT : mode_t = 61440;
+ pub static S_IEXEC : mode_t = 64;
+ pub static S_IWRITE : mode_t = 128;
+ pub static S_IREAD : mode_t = 256;
+ pub static S_IRWXU : mode_t = 448;
+ pub static S_IXUSR : mode_t = 64;
+ pub static S_IWUSR : mode_t = 128;
+ pub static S_IRUSR : mode_t = 256;
pub static F_OK : c_int = 0;
pub static R_OK : c_int = 4;
pub static W_OK : c_int = 2;
pub mod posix88 {
use types::common::c95::c_void;
use types::os::arch::c95::c_int;
+ use types::os::arch::posix88::mode_t;
pub static O_RDONLY : c_int = 0;
pub static O_WRONLY : c_int = 1;
pub static O_CREAT : c_int = 512;
pub static O_EXCL : c_int = 2048;
pub static O_TRUNC : c_int = 1024;
- pub static S_IFIFO : c_int = 4096;
- pub static S_IFCHR : c_int = 8192;
- pub static S_IFBLK : c_int = 24576;
- pub static S_IFDIR : c_int = 16384;
- pub static S_IFREG : c_int = 32768;
- pub static S_IFLNK : c_int = 40960;
- pub static S_IFMT : c_int = 61440;
- pub static S_IEXEC : c_int = 64;
- pub static S_IWRITE : c_int = 128;
- pub static S_IREAD : c_int = 256;
- pub static S_IRWXU : c_int = 448;
- pub static S_IXUSR : c_int = 64;
- pub static S_IWUSR : c_int = 128;
- pub static S_IRUSR : c_int = 256;
+ pub static S_IFIFO : mode_t = 4096;
+ pub static S_IFCHR : mode_t = 8192;
+ pub static S_IFBLK : mode_t = 24576;
+ pub static S_IFDIR : mode_t = 16384;
+ pub static S_IFREG : mode_t = 32768;
+ pub static S_IFLNK : mode_t = 40960;
+ pub static S_IFMT : mode_t = 61440;
+ pub static S_IEXEC : mode_t = 64;
+ pub static S_IWRITE : mode_t = 128;
+ pub static S_IREAD : mode_t = 256;
+ pub static S_IRWXU : mode_t = 448;
+ pub static S_IXUSR : mode_t = 64;
+ pub static S_IWUSR : mode_t = 128;
+ pub static S_IRUSR : mode_t = 256;
pub static F_OK : c_int = 0;
pub static R_OK : c_int = 4;
pub static W_OK : c_int = 2;
pub mod posix88 {
use types::common::c95::c_void;
use types::os::arch::c95::c_int;
+ use types::os::arch::posix88::mode_t;
pub static O_RDONLY : c_int = 0;
pub static O_WRONLY : c_int = 1;
pub static O_CREAT : c_int = 512;
pub static O_EXCL : c_int = 2048;
pub static O_TRUNC : c_int = 1024;
- pub static S_IFIFO : c_int = 4096;
- pub static S_IFCHR : c_int = 8192;
- pub static S_IFBLK : c_int = 24576;
- pub static S_IFDIR : c_int = 16384;
- pub static S_IFREG : c_int = 32768;
- pub static S_IFLNK : c_int = 40960;
- pub static S_IFMT : c_int = 61440;
- pub static S_IEXEC : c_int = 64;
- pub static S_IWRITE : c_int = 128;
- pub static S_IREAD : c_int = 256;
- pub static S_IRWXU : c_int = 448;
- pub static S_IXUSR : c_int = 64;
- pub static S_IWUSR : c_int = 128;
- pub static S_IRUSR : c_int = 256;
+ pub static S_IFIFO : mode_t = 4096;
+ pub static S_IFCHR : mode_t = 8192;
+ pub static S_IFBLK : mode_t = 24576;
+ pub static S_IFDIR : mode_t = 16384;
+ pub static S_IFREG : mode_t = 32768;
+ pub static S_IFLNK : mode_t = 40960;
+ pub static S_IFMT : mode_t = 61440;
+ pub static S_IEXEC : mode_t = 64;
+ pub static S_IWRITE : mode_t = 128;
+ pub static S_IREAD : mode_t = 256;
+ pub static S_IRWXU : mode_t = 448;
+ pub static S_IXUSR : mode_t = 64;
+ pub static S_IWUSR : mode_t = 128;
+ pub static S_IRUSR : mode_t = 256;
pub static F_OK : c_int = 0;
pub static R_OK : c_int = 4;
pub static W_OK : c_int = 2;
use types::os::arch::posix88::mode_t;
extern {
- pub fn open(path: *const c_char, oflag: c_int, mode: c_int)
+ pub fn open(path: *const c_char, oflag: c_int, mode: mode_t)
-> c_int;
pub fn creat(path: *const c_char, mode: mode_t) -> c_int;
pub fn fcntl(fd: c_int, cmd: c_int, ...) -> c_int;
*/
-#![crate_id = "log#0.11.0"]
+#![crate_name = "log"]
#![experimental]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
-
#![feature(macro_rules)]
#![deny(missing_doc)]
None => Err(IoError {
code: libc::ERROR_INVALID_NAME as uint,
extra: 0,
- detail: Some("valid unicode input required".to_str()),
+ detail: Some("valid unicode input required".to_string()),
})
}
}
return Err(IoError {
code: ERROR as uint,
extra: 0,
- detail: Some("path must be smaller than SUN_LEN".to_str()),
+ detail: Some("path must be smaller than SUN_LEN".to_string()),
})
}
s.sun_family = libc::AF_UNIX as libc::sa_family_t;
Err(IoError {
code: libc::ERROR_OPERATION_ABORTED as uint,
extra: amt,
- detail: Some("short write during write".to_str()),
+ detail: Some("short write during write".to_string()),
})
} else {
Err(util::timeout("write timed out"))
Some(..) => return Err(IoError {
code: ERROR as uint,
extra: 0,
- detail: Some("can't kill an exited process".to_str()),
+ detail: Some("can't kill an exited process".to_string()),
}),
None => {}
}
return Err(IoError {
code: libc::ERROR_CALL_NOT_IMPLEMENTED as uint,
extra: 0,
- detail: Some("unsupported gid/uid requested on windows".to_str()),
+ detail: Some("unsupported gid/uid requested on windows".to_string()),
})
}
+ // To have the spawning semantics of unix/windows stay the same, we need to
+ // read the *child's* PATH if one is provided. See #15149 for more details.
+ let program = cfg.env.and_then(|env| {
+ for &(ref key, ref v) in env.iter() {
+ if b"PATH" != key.as_bytes_no_nul() { continue }
+
+ // Split the value and test each path to see if the program exists.
+ for path in os::split_paths(v.as_bytes_no_nul()).move_iter() {
+ let path = path.join(cfg.program.as_bytes_no_nul())
+ .with_extension(os::consts::EXE_EXTENSION);
+ if path.exists() {
+ return Some(path.to_c_str())
+ }
+ }
+ break
+ }
+ None
+ });
+
unsafe {
let mut si = zeroed_startupinfo();
si.cb = mem::size_of::<STARTUPINFO>() as DWORD;
try!(set_fd(&out_fd, &mut si.hStdOutput, false));
try!(set_fd(&err_fd, &mut si.hStdError, false));
- let cmd_str = make_command_line(cfg.program, cfg.args);
+ let cmd_str = make_command_line(program.as_ref().unwrap_or(cfg.program),
+ cfg.args);
let mut pi = zeroed_process_information();
let mut create_err = None;
}
#[cfg(unix)]
-fn with_envp<T>(env: Option<&[(CString, CString)]>,
+fn with_envp<T>(env: Option<&[(&CString, &CString)]>,
cb: proc(*const c_void) -> T) -> T {
// On posixy systems we can pass a char** for envp, which is a
// null-terminated array of "k=v\0" strings. Since we must create
}
#[cfg(windows)]
-fn with_envp<T>(env: Option<&[(CString, CString)]>, cb: |*mut c_void| -> T) -> T {
+fn with_envp<T>(env: Option<&[(&CString, &CString)]>, cb: |*mut c_void| -> T) -> T {
// On win32 we pass an "environment block" which is not a char**, but
// rather a concatenation of null-terminated k=v\0 sequences, with a final
// \0 to terminate.
IoError {
code: ERROR as uint,
extra: 0,
- detail: Some(desc.to_str()),
+ detail: Some(desc.to_string()),
}
}
IoError {
code: ERROR as uint,
extra: n,
- detail: Some(desc.to_str()),
+ detail: Some(desc.to_string()),
}
}
//! }
//! ```
-#![crate_id = "native#0.11.0"]
+#![crate_name = "native"]
#![experimental]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+ html_root_url = "http://doc.rust-lang.org/master/")]
#![deny(unused_result, unused_must_use)]
#![allow(non_camel_case_types, deprecated)]
// attempt to allocate a vector of size (-1u) == huge.
let x: BigInt =
from_str(format!("1{}", "0".repeat(36)).as_slice()).unwrap();
- let _y = x.to_str();
+ let _y = x.to_string();
}
#[test]
}
#[bench]
- fn to_str(b: &mut Bencher) {
+ fn to_string(b: &mut Bencher) {
let fac = factorial(100);
let fib = fib(100);
b.iter(|| {
- fac.to_str();
+ fac.to_string();
});
b.iter(|| {
- fib.to_str();
+ fib.to_string();
});
}
}
#[test]
- fn test_to_str() {
+ fn test_to_string() {
fn test(c : Complex64, s: String) {
- assert_eq!(c.to_str(), s);
+ assert_eq!(c.to_string(), s);
}
test(_0_0i, "0+0i".to_string());
test(_1_0i, "1+0i".to_string());
#![feature(macro_rules)]
-#![crate_id = "num#0.11.0"]
+#![crate_name = "num"]
#![experimental]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
-
#![allow(deprecated)] // from_str_radix
extern crate rand;
use std::cmp;
use std::fmt;
use std::from_str::FromStr;
+use std::num;
use std::num::{Zero, One, ToStrRadix, FromStrRadix};
+
use bigint::{BigInt, BigUint, Sign, Plus, Minus};
/// Represents the ratio between 2 numbers.
impl<T: Clone + Integer + PartialOrd>
Num for Ratio<T> {}
+impl<T: Clone + Integer + PartialOrd>
+ num::Signed for Ratio<T> {
+ #[inline]
+ fn abs(&self) -> Ratio<T> {
+ if self.is_negative() { -self.clone() } else { self.clone() }
+ }
+
+ #[inline]
+ fn abs_sub(&self, other: &Ratio<T>) -> Ratio<T> {
+ if *self <= *other { Zero::zero() } else { *self - *other }
+ }
+
+ #[inline]
+ fn signum(&self) -> Ratio<T> {
+ if *self > Zero::zero() {
+ num::one()
+ } else if self.is_zero() {
+ num::zero()
+ } else {
+ - num::one::<Ratio<T>>()
+ }
+ }
+
+ #[inline]
+ fn is_positive(&self) -> bool { *self > Zero::zero() }
+
+ #[inline]
+ fn is_negative(&self) -> bool { *self < Zero::zero() }
+}
+
/* String conversions */
impl<T: fmt::Show + Eq + One> fmt::Show for Ratio<T> {
/// Renders as `numer/denom`. If denom=1, renders as numer.
use super::{Ratio, Rational, BigRational};
use std::num::{Zero, One, FromStrRadix, FromPrimitive, ToStrRadix};
use std::from_str::FromStr;
+ use std::num;
pub static _0 : Rational = Ratio { numer: 0, denom: 1};
pub static _1 : Rational = Ratio { numer: 1, denom: 1};
fn test_to_from_str() {
fn test(r: Rational, s: String) {
assert_eq!(FromStr::from_str(s.as_slice()), Some(r));
- assert_eq!(r.to_str(), s);
+ assert_eq!(r.to_string(), s);
}
test(_1, "1".to_string());
test(_0, "0".to_string());
assert_eq!(Ratio::from_float(f64::INFINITY), None);
assert_eq!(Ratio::from_float(f64::NEG_INFINITY), None);
}
+
+ #[test]
+ fn test_signed() {
+ assert_eq!(_neg1_2.abs(), _1_2);
+ assert_eq!(_3_2.abs_sub(&_1_2), _1);
+ assert_eq!(_1_2.abs_sub(&_3_2), Zero::zero());
+ assert_eq!(_1_2.signum(), One::one());
+ assert_eq!(_neg1_2.signum(), - num::one::<Ratio<int>>());
+ assert!(_neg1_2.is_negative());
+ assert!(! _neg1_2.is_positive());
+ assert!(! _1_2.is_negative());
+ }
}
//! is not recommended to use this library directly, but rather the official
//! interface through `std::rand`.
-#![crate_id = "rand#0.11.0"]
+#![crate_name = "rand"]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
#![feature(macro_rules, phase, globs)]
//!
//! ## Perl character classes (Unicode friendly)
//!
+//! These classes are based on the definitions provided in
+//! [UTS#18](http://www.unicode.org/reports/tr18/#Compatibility_Properties):
+//!
//! <pre class="rust">
-//! \d digit ([0-9] + \p{Nd})
+//! \d digit (\p{Nd})
//! \D not digit
-//! \s whitespace ([\t\n\f\r ] + \p{Z})
+//! \s whitespace (\p{White_Space})
//! \S not whitespace
-//! \w word character ([0-9A-Za-z_] + \p{L})
+//! \w word character (\p{Alphabetic} + \p{M} + \d + \p{Pc} + \p{Join_Control})
//! \W not word character
//! </pre>
//!
//! characters in the search text and `m` is the number of instructions in a
//! compiled expression.
-#![crate_id = "regex#0.11.0"]
+#![crate_name = "regex"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![experimental]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
#![feature(macro_rules, phase)]
#[cfg(test)]
extern crate regex;
+// unicode tables for character classes are defined in libunicode
+extern crate unicode;
+
pub use parse::Error;
pub use re::{Regex, Captures, SubCaptures, SubCapturesPos};
pub use re::{FindCaptures, FindMatches};
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::char;
+use std::cmp;
+use std::fmt;
+use std::iter;
+use std::num;
+use std::str;
+
+/// Static data containing Unicode ranges for general categories and scripts.
+use unicode::regex::{UNICODE_CLASSES, PERLD, PERLS, PERLW};
+
+/// The maximum number of repetitions allowed with the `{n,m}` syntax.
+static MAX_REPEAT: uint = 1000;
+
+/// Error corresponds to something that can go wrong while parsing
+/// a regular expression.
+///
+/// (Once an expression is compiled, it is not possible to produce an error
+/// via searching, splitting or replacing.)
+pub struct Error {
+ /// The *approximate* character index of where the error occurred.
+ pub pos: uint,
+ /// A message describing the error.
+ pub msg: String,
+}
+
+impl fmt::Show for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "Regex syntax error near position {}: {}",
+ self.pos, self.msg)
+ }
+}
+
+/// Represents the abstract syntax of a regular expression.
+/// It is showable so that error messages resulting from a bug can provide
+/// useful information.
+/// It is cloneable so that expressions can be repeated for the counted
+/// repetition feature. (No other copying is done.)
+///
+/// Note that this representation prevents one from reproducing the regex as
+/// it was typed. (But it could be used to reproduce an equivalent regex.)
+#[deriving(Show, Clone)]
+pub enum Ast {
+ Nothing,
+ Literal(char, Flags),
+ Dot(Flags),
+ Class(Vec<(char, char)>, Flags),
+ Begin(Flags),
+ End(Flags),
+ WordBoundary(Flags),
+ Capture(uint, Option<String>, Box<Ast>),
+ // Represent concatenation as a flat vector to avoid blowing the
+ // stack in the compiler.
+ Cat(Vec<Ast>),
+ Alt(Box<Ast>, Box<Ast>),
+ Rep(Box<Ast>, Repeater, Greed),
+}
+
+#[deriving(Show, PartialEq, Clone)]
+pub enum Repeater {
+ ZeroOne,
+ ZeroMore,
+ OneMore,
+}
+
+#[deriving(Show, Clone)]
+pub enum Greed {
+ Greedy,
+ Ungreedy,
+}
+
+impl Greed {
+ pub fn is_greedy(&self) -> bool {
+ match *self {
+ Greedy => true,
+ _ => false,
+ }
+ }
+
+ fn swap(self, swapped: bool) -> Greed {
+ if !swapped { return self }
+ match self {
+ Greedy => Ungreedy,
+ Ungreedy => Greedy,
+ }
+ }
+}
+
+/// BuildAst is a regrettable type that represents intermediate state for
+/// constructing an abstract syntax tree. Its central purpose is to facilitate
+/// parsing groups and alternations while also maintaining a stack of flag
+/// state.
+#[deriving(Show)]
+enum BuildAst {
+ Ast(Ast),
+ Paren(Flags, uint, String), // '('
+ Bar, // '|'
+}
+
+impl BuildAst {
+ fn paren(&self) -> bool {
+ match *self {
+ Paren(_, _, _) => true,
+ _ => false,
+ }
+ }
+
+ fn flags(&self) -> Flags {
+ match *self {
+ Paren(flags, _, _) => flags,
+ _ => fail!("Cannot get flags from {}", self),
+ }
+ }
+
+ fn capture(&self) -> Option<uint> {
+ match *self {
+ Paren(_, 0, _) => None,
+ Paren(_, c, _) => Some(c),
+ _ => fail!("Cannot get capture group from {}", self),
+ }
+ }
+
+ fn capture_name(&self) -> Option<String> {
+ match *self {
+ Paren(_, 0, _) => None,
+ Paren(_, _, ref name) => {
+ if name.len() == 0 {
+ None
+ } else {
+ Some(name.clone())
+ }
+ }
+ _ => fail!("Cannot get capture name from {}", self),
+ }
+ }
+
+ fn bar(&self) -> bool {
+ match *self {
+ Bar => true,
+ _ => false,
+ }
+ }
+
+ fn unwrap(self) -> Result<Ast, Error> {
+ match self {
+ Ast(x) => Ok(x),
+ _ => fail!("Tried to unwrap non-AST item: {}", self),
+ }
+ }
+}
+
+/// Flags represents all options that can be twiddled by a user in an
+/// expression.
+pub type Flags = u8;
+
+pub static FLAG_EMPTY: u8 = 0;
+pub static FLAG_NOCASE: u8 = 1 << 0; // i
+pub static FLAG_MULTI: u8 = 1 << 1; // m
+pub static FLAG_DOTNL: u8 = 1 << 2; // s
+pub static FLAG_SWAP_GREED: u8 = 1 << 3; // U
+pub static FLAG_NEGATED: u8 = 1 << 4; // char class or not word boundary
+
+struct Parser<'a> {
+ // The input, parsed only as a sequence of UTF8 code points.
+ chars: Vec<char>,
+ // The index of the current character in the input.
+ chari: uint,
+ // The intermediate state representing the AST.
+ stack: Vec<BuildAst>,
+ // The current set of flags.
+ flags: Flags,
+ // The total number of capture groups.
+ // Incremented each time an opening left paren is seen (assuming it is
+ // opening a capture group).
+ caps: uint,
+ // A set of all capture group names used only to detect duplicates.
+ names: Vec<String>,
+}
+
+pub fn parse(s: &str) -> Result<Ast, Error> {
+ Parser {
+ chars: s.chars().collect(),
+ chari: 0,
+ stack: vec!(),
+ flags: FLAG_EMPTY,
+ caps: 0,
+ names: vec!(),
+ }.parse()
+}
+
+impl<'a> Parser<'a> {
+ fn parse(&mut self) -> Result<Ast, Error> {
+ if self.chars.len() == 0 {
+ return Ok(Nothing);
+ }
+ loop {
+ let c = self.cur();
+ match c {
+ '?' | '*' | '+' => try!(self.push_repeater(c)),
+ '\\' => {
+ let ast = try!(self.parse_escape());
+ self.push(ast)
+ }
+ '{' => try!(self.parse_counted()),
+ '[' => match self.try_parse_ascii() {
+ None => try!(self.parse_class()),
+ Some(class) => self.push(class),
+ },
+ '(' => {
+ if self.peek_is(1, '?') {
+ try!(self.expect('?'))
+ try!(self.parse_group_opts())
+ } else {
+ self.caps += 1;
+ self.stack.push(Paren(self.flags,
+ self.caps,
+ "".to_string()))
+ }
+ }
+ ')' => {
+ let catfrom = try!(
+ self.pos_last(false, |x| x.paren() || x.bar()));
+ try!(self.concat(catfrom));
+
+ let altfrom = try!(self.pos_last(false, |x| x.paren()));
+ // Before we smush the alternates together and pop off the
+ // left paren, let's grab the old flags and see if we
+ // need a capture.
+ let (cap, cap_name, oldflags) = {
+ let paren = self.stack.get(altfrom-1);
+ (paren.capture(), paren.capture_name(), paren.flags())
+ };
+ try!(self.alternate(altfrom));
+ self.flags = oldflags;
+
+ // If this was a capture, pop what we just pushed in
+ // alternate and make it a capture.
+ if cap.is_some() {
+ let ast = try!(self.pop_ast());
+ self.push(Capture(cap.unwrap(), cap_name, box ast));
+ }
+ }
+ '|' => {
+ let catfrom = try!(
+ self.pos_last(true, |x| x.paren() || x.bar()));
+ try!(self.concat(catfrom));
+
+ self.stack.push(Bar);
+ }
+ _ => try!(self.push_literal(c)),
+ }
+ if !self.next_char() {
+ break
+ }
+ }
+
+ // Try to improve error handling. At this point, there should be
+ // no remaining open parens.
+ if self.stack.iter().any(|x| x.paren()) {
+ return self.err("Unclosed parenthesis.")
+ }
+ let catfrom = try!(self.pos_last(true, |x| x.bar()));
+ try!(self.concat(catfrom));
+ try!(self.alternate(0));
+
+ assert!(self.stack.len() == 1);
+ self.pop_ast()
+ }
+
+ fn noteof(&mut self, expected: &str) -> Result<(), Error> {
+ match self.next_char() {
+ true => Ok(()),
+ false => {
+ self.err(format!("Expected {} but got EOF.",
+ expected).as_slice())
+ }
+ }
+ }
+
+ fn expect(&mut self, expected: char) -> Result<(), Error> {
+ match self.next_char() {
+ true if self.cur() == expected => Ok(()),
+ true => self.err(format!("Expected '{}' but got '{}'.",
+ expected, self.cur()).as_slice()),
+ false => {
+ self.err(format!("Expected '{}' but got EOF.",
+ expected).as_slice())
+ }
+ }
+ }
+
+ fn next_char(&mut self) -> bool {
+ self.chari += 1;
+ self.chari < self.chars.len()
+ }
+
+ fn pop_ast(&mut self) -> Result<Ast, Error> {
+ match self.stack.pop().unwrap().unwrap() {
+ Err(e) => Err(e),
+ Ok(ast) => Ok(ast),
+ }
+ }
+
+ fn push(&mut self, ast: Ast) {
+ self.stack.push(Ast(ast))
+ }
+
+ fn push_repeater(&mut self, c: char) -> Result<(), Error> {
+ if self.stack.len() == 0 {
+ return self.err(
+ "A repeat operator must be preceded by a valid expression.")
+ }
+ let rep: Repeater = match c {
+ '?' => ZeroOne, '*' => ZeroMore, '+' => OneMore,
+ _ => fail!("Not a valid repeater operator."),
+ };
+
+ match self.peek(1) {
+ Some('*') | Some('+') =>
+ return self.err(
+ "Double repeat operators are not supported."),
+ _ => {},
+ }
+ let ast = try!(self.pop_ast());
+ match ast {
+ Begin(_) | End(_) | WordBoundary(_) =>
+ return self.err(
+ "Repeat arguments cannot be empty width assertions."),
+ _ => {}
+ }
+ let greed = try!(self.get_next_greedy());
+ self.push(Rep(box ast, rep, greed));
+ Ok(())
+ }
+
+ fn push_literal(&mut self, c: char) -> Result<(), Error> {
+ let flags = self.flags;
+ match c {
+ '.' => {
+ self.push(Dot(flags))
+ }
+ '^' => {
+ self.push(Begin(flags))
+ }
+ '$' => {
+ self.push(End(flags))
+ }
+ _ => {
+ self.push(Literal(c, flags))
+ }
+ }
+ Ok(())
+ }
+
+ // Parses all forms of character classes.
+ // Assumes that '[' is the current character.
+ fn parse_class(&mut self) -> Result<(), Error> {
+ let negated =
+ if self.peek_is(1, '^') {
+ try!(self.expect('^'))
+ FLAG_NEGATED
+ } else {
+ FLAG_EMPTY
+ };
+ let mut ranges: Vec<(char, char)> = vec!();
+ let mut alts: Vec<Ast> = vec!();
+
+ if self.peek_is(1, ']') {
+ try!(self.expect(']'))
+ ranges.push((']', ']'))
+ }
+ while self.peek_is(1, '-') {
+ try!(self.expect('-'))
+ ranges.push(('-', '-'))
+ }
+ loop {
+ try!(self.noteof("a closing ']' or a non-empty character class)"))
+ let mut c = self.cur();
+ match c {
+ '[' =>
+ match self.try_parse_ascii() {
+ Some(Class(asciis, flags)) => {
+ alts.push(Class(asciis, flags ^ negated));
+ continue
+ }
+ Some(ast) =>
+ fail!("Expected Class AST but got '{}'", ast),
+ // Just drop down and try to add as a regular character.
+ None => {},
+ },
+ '\\' => {
+ match try!(self.parse_escape()) {
+ Class(asciis, flags) => {
+ alts.push(Class(asciis, flags ^ negated));
+ continue
+ }
+ Literal(c2, _) => c = c2, // process below
+ Begin(_) | End(_) | WordBoundary(_) =>
+ return self.err(
+ "\\A, \\z, \\b and \\B are not valid escape \
+ sequences inside a character class."),
+ ast => fail!("Unexpected AST item '{}'", ast),
+ }
+ }
+ _ => {},
+ }
+ match c {
+ ']' => {
+ if ranges.len() > 0 {
+ let flags = negated | (self.flags & FLAG_NOCASE);
+ let mut ast = Class(combine_ranges(ranges), flags);
+ for alt in alts.move_iter() {
+ ast = Alt(box alt, box ast)
+ }
+ self.push(ast);
+ } else if alts.len() > 0 {
+ let mut ast = alts.pop().unwrap();
+ for alt in alts.move_iter() {
+ ast = Alt(box alt, box ast)
+ }
+ self.push(ast);
+ }
+ return Ok(())
+ }
+ c => {
+ if self.peek_is(1, '-') && !self.peek_is(2, ']') {
+ try!(self.expect('-'))
+ try!(self.noteof("not a ']'"))
+ let c2 = self.cur();
+ if c2 < c {
+ return self.err(format!("Invalid character class \
+ range '{}-{}'",
+ c,
+ c2).as_slice())
+ }
+ ranges.push((c, self.cur()))
+ } else {
+ ranges.push((c, c))
+ }
+ }
+ }
+ }
+ }
+
+ // Tries to parse an ASCII character class of the form [:name:].
+ // If successful, returns an AST character class corresponding to name
+ // and moves the parser to the final ']' character.
+ // If unsuccessful, no state is changed and None is returned.
+ // Assumes that '[' is the current character.
+ fn try_parse_ascii(&mut self) -> Option<Ast> {
+ if !self.peek_is(1, ':') {
+ return None
+ }
+ let closer =
+ match self.pos(']') {
+ Some(i) => i,
+ None => return None,
+ };
+ if *self.chars.get(closer-1) != ':' {
+ return None
+ }
+ if closer - self.chari <= 3 {
+ return None
+ }
+ let mut name_start = self.chari + 2;
+ let negated =
+ if self.peek_is(2, '^') {
+ name_start += 1;
+ FLAG_NEGATED
+ } else {
+ FLAG_EMPTY
+ };
+ let name = self.slice(name_start, closer - 1);
+ match find_class(ASCII_CLASSES, name.as_slice()) {
+ None => None,
+ Some(ranges) => {
+ self.chari = closer;
+ let flags = negated | (self.flags & FLAG_NOCASE);
+ Some(Class(combine_ranges(ranges), flags))
+ }
+ }
+ }
+
+ // Parses counted repetition. Supports:
+ // {n}, {n,}, {n,m}, {n}?, {n,}? and {n,m}?
+ // Assumes that '{' is the current character.
+ // Returns either an error or moves the parser to the final '}' character.
+ // (Or the '?' character if not greedy.)
+ fn parse_counted(&mut self) -> Result<(), Error> {
+ // Scan until the closing '}' and grab the stuff in {}.
+ let start = self.chari;
+ let closer =
+ match self.pos('}') {
+ Some(i) => i,
+ None => {
+ return self.err(format!("No closing brace for counted \
+ repetition starting at position \
+ {}.",
+ start).as_slice())
+ }
+ };
+ self.chari = closer;
+ let greed = try!(self.get_next_greedy());
+ let inner = str::from_chars(
+ self.chars.as_slice().slice(start + 1, closer));
+
+ // Parse the min and max values from the regex.
+ let (mut min, mut max): (uint, Option<uint>);
+ if !inner.as_slice().contains(",") {
+ min = try!(self.parse_uint(inner.as_slice()));
+ max = Some(min);
+ } else {
+ let pieces: Vec<&str> = inner.as_slice().splitn(',', 1).collect();
+ let (smin, smax) = (*pieces.get(0), *pieces.get(1));
+ if smin.len() == 0 {
+ return self.err("Max repetitions cannot be specified \
+ without min repetitions.")
+ }
+ min = try!(self.parse_uint(smin));
+ max =
+ if smax.len() == 0 {
+ None
+ } else {
+ Some(try!(self.parse_uint(smax)))
+ };
+ }
+
+ // Do some bounds checking and make sure max >= min.
+ if min > MAX_REPEAT {
+ return self.err(format!(
+ "{} exceeds maximum allowed repetitions ({})",
+ min, MAX_REPEAT).as_slice());
+ }
+ if max.is_some() {
+ let m = max.unwrap();
+ if m > MAX_REPEAT {
+ return self.err(format!(
+ "{} exceeds maximum allowed repetitions ({})",
+ m, MAX_REPEAT).as_slice());
+ }
+ if m < min {
+ return self.err(format!(
+ "Max repetitions ({}) cannot be smaller than min \
+ repetitions ({}).", m, min).as_slice());
+ }
+ }
+
+ // Now manipulate the AST be repeating elements.
+ if max.is_none() {
+ // Require N copies of what's on the stack and then repeat it.
+ let ast = try!(self.pop_ast());
+ for _ in iter::range(0, min) {
+ self.push(ast.clone())
+ }
+ self.push(Rep(box ast, ZeroMore, greed));
+ } else {
+ // Require N copies of what's on the stack and then repeat it
+ // up to M times optionally.
+ let ast = try!(self.pop_ast());
+ for _ in iter::range(0, min) {
+ self.push(ast.clone())
+ }
+ if max.is_some() {
+ for _ in iter::range(min, max.unwrap()) {
+ self.push(Rep(box ast.clone(), ZeroOne, greed))
+ }
+ }
+ // It's possible that we popped something off the stack but
+ // never put anything back on it. To keep things simple, add
+ // a no-op expression.
+ if min == 0 && (max.is_none() || max == Some(0)) {
+ self.push(Nothing)
+ }
+ }
+ Ok(())
+ }
+
+ // Parses all escape sequences.
+ // Assumes that '\' is the current character.
+ fn parse_escape(&mut self) -> Result<Ast, Error> {
+ try!(self.noteof("an escape sequence following a '\\'"))
+
+ let c = self.cur();
+ if is_punct(c) {
+ return Ok(Literal(c, FLAG_EMPTY))
+ }
+ match c {
+ 'a' => Ok(Literal('\x07', FLAG_EMPTY)),
+ 'f' => Ok(Literal('\x0C', FLAG_EMPTY)),
+ 't' => Ok(Literal('\t', FLAG_EMPTY)),
+ 'n' => Ok(Literal('\n', FLAG_EMPTY)),
+ 'r' => Ok(Literal('\r', FLAG_EMPTY)),
+ 'v' => Ok(Literal('\x0B', FLAG_EMPTY)),
+ 'A' => Ok(Begin(FLAG_EMPTY)),
+ 'z' => Ok(End(FLAG_EMPTY)),
+ 'b' => Ok(WordBoundary(FLAG_EMPTY)),
+ 'B' => Ok(WordBoundary(FLAG_NEGATED)),
+ '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7' => Ok(try!(self.parse_octal())),
+ 'x' => Ok(try!(self.parse_hex())),
+ 'p' | 'P' => Ok(try!(self.parse_unicode_name())),
+ 'd' | 'D' | 's' | 'S' | 'w' | 'W' => {
+ let ranges = perl_unicode_class(c);
+ let mut flags = self.flags & FLAG_NOCASE;
+ if c.is_uppercase() { flags |= FLAG_NEGATED }
+ Ok(Class(ranges, flags))
+ }
+ _ => {
+ self.err(format!("Invalid escape sequence '\\\\{}'",
+ c).as_slice())
+ }
+ }
+ }
+
+ // Parses a unicode character class name, either of the form \pF where
+ // F is a one letter unicode class name or of the form \p{name} where
+ // name is the unicode class name.
+ // Assumes that \p or \P has been read (and 'p' or 'P' is the current
+ // character).
+ fn parse_unicode_name(&mut self) -> Result<Ast, Error> {
+ let negated = if self.cur() == 'P' { FLAG_NEGATED } else { FLAG_EMPTY };
+ let mut name: String;
+ if self.peek_is(1, '{') {
+ try!(self.expect('{'))
+ let closer =
+ match self.pos('}') {
+ Some(i) => i,
+ None => return self.err(format!(
+ "Missing '}}' for unclosed '{{' at position {}",
+ self.chari).as_slice()),
+ };
+ if closer - self.chari + 1 == 0 {
+ return self.err("No Unicode class name found.")
+ }
+ name = self.slice(self.chari + 1, closer);
+ self.chari = closer;
+ } else {
+ if self.chari + 1 >= self.chars.len() {
+ return self.err("No single letter Unicode class name found.")
+ }
+ name = self.slice(self.chari + 1, self.chari + 2);
+ self.chari += 1;
+ }
+ match find_class(UNICODE_CLASSES, name.as_slice()) {
+ None => {
+ return self.err(format!("Could not find Unicode class '{}'",
+ name).as_slice())
+ }
+ Some(ranges) => {
+ Ok(Class(ranges, negated | (self.flags & FLAG_NOCASE)))
+ }
+ }
+ }
+
+ // Parses an octal number, up to 3 digits.
+ // Assumes that \n has been read, where n is the first digit.
+ fn parse_octal(&mut self) -> Result<Ast, Error> {
+ let start = self.chari;
+ let mut end = start + 1;
+ let (d2, d3) = (self.peek(1), self.peek(2));
+ if d2 >= Some('0') && d2 <= Some('7') {
+ try!(self.noteof("expected octal character in [0-7]"))
+ end += 1;
+ if d3 >= Some('0') && d3 <= Some('7') {
+ try!(self.noteof("expected octal character in [0-7]"))
+ end += 1;
+ }
+ }
+ let s = self.slice(start, end);
+ match num::from_str_radix::<u32>(s.as_slice(), 8) {
+ Some(n) => Ok(Literal(try!(self.char_from_u32(n)), FLAG_EMPTY)),
+ None => {
+ self.err(format!("Could not parse '{}' as octal number.",
+ s).as_slice())
+ }
+ }
+ }
+
+ // Parse a hex number. Either exactly two digits or anything in {}.
+ // Assumes that \x has been read.
+ fn parse_hex(&mut self) -> Result<Ast, Error> {
+ if !self.peek_is(1, '{') {
+ try!(self.expect('{'))
+ return self.parse_hex_two()
+ }
+ let start = self.chari + 2;
+ let closer =
+ match self.pos('}') {
+ None => {
+ return self.err(format!("Missing '}}' for unclosed \
+ '{{' at position {}",
+ start).as_slice())
+ }
+ Some(i) => i,
+ };
+ self.chari = closer;
+ self.parse_hex_digits(self.slice(start, closer).as_slice())
+ }
+
+ // Parses a two-digit hex number.
+ // Assumes that \xn has been read, where n is the first digit and is the
+ // current character.
+ // After return, parser will point at the second digit.
+ fn parse_hex_two(&mut self) -> Result<Ast, Error> {
+ let (start, end) = (self.chari, self.chari + 2);
+ let bad = self.slice(start - 2, self.chars.len());
+ try!(self.noteof(format!("Invalid hex escape sequence '{}'",
+ bad).as_slice()))
+ self.parse_hex_digits(self.slice(start, end).as_slice())
+ }
+
+ // Parses `s` as a hexadecimal number.
+ fn parse_hex_digits(&self, s: &str) -> Result<Ast, Error> {
+ match num::from_str_radix::<u32>(s, 16) {
+ Some(n) => Ok(Literal(try!(self.char_from_u32(n)), FLAG_EMPTY)),
+ None => {
+ self.err(format!("Could not parse '{}' as hex number.",
+ s).as_slice())
+ }
+ }
+ }
+
+ // Parses a named capture.
+ // Assumes that '(?P<' has been consumed and that the current character
+ // is '<'.
+ // When done, parser will be at the closing '>' character.
+ fn parse_named_capture(&mut self) -> Result<(), Error> {
+ try!(self.noteof("a capture name"))
+ let closer =
+ match self.pos('>') {
+ Some(i) => i,
+ None => return self.err("Capture name must end with '>'."),
+ };
+ if closer - self.chari == 0 {
+ return self.err("Capture names must have at least 1 character.")
+ }
+ let name = self.slice(self.chari, closer);
+ if !name.as_slice().chars().all(is_valid_cap) {
+ return self.err(
+ "Capture names can only have underscores, letters and digits.")
+ }
+ if self.names.contains(&name) {
+ return self.err(format!("Duplicate capture group name '{}'.",
+ name).as_slice())
+ }
+ self.names.push(name.clone());
+ self.chari = closer;
+ self.caps += 1;
+ self.stack.push(Paren(self.flags, self.caps, name));
+ Ok(())
+ }
+
+ // Parses non-capture groups and options.
+ // Assumes that '(?' has already been consumed and '?' is the current
+ // character.
+ fn parse_group_opts(&mut self) -> Result<(), Error> {
+ if self.peek_is(1, 'P') && self.peek_is(2, '<') {
+ try!(self.expect('P')) try!(self.expect('<'))
+ return self.parse_named_capture()
+ }
+ let start = self.chari;
+ let mut flags = self.flags;
+ let mut sign = 1i;
+ let mut saw_flag = false;
+ loop {
+ try!(self.noteof("expected non-empty set of flags or closing ')'"))
+ match self.cur() {
+ 'i' => { flags = flags | FLAG_NOCASE; saw_flag = true},
+ 'm' => { flags = flags | FLAG_MULTI; saw_flag = true},
+ 's' => { flags = flags | FLAG_DOTNL; saw_flag = true},
+ 'U' => { flags = flags | FLAG_SWAP_GREED; saw_flag = true},
+ '-' => {
+ if sign < 0 {
+ return self.err(format!(
+ "Cannot negate flags twice in '{}'.",
+ self.slice(start, self.chari + 1)).as_slice())
+ }
+ sign = -1;
+ saw_flag = false;
+ flags = flags ^ flags;
+ }
+ ':' | ')' => {
+ if sign < 0 {
+ if !saw_flag {
+ return self.err(format!(
+ "A valid flag does not follow negation in '{}'",
+ self.slice(start, self.chari + 1)).as_slice())
+ }
+ flags = flags ^ flags;
+ }
+ if self.cur() == ':' {
+ // Save the old flags with the opening paren.
+ self.stack.push(Paren(self.flags, 0, "".to_string()));
+ }
+ self.flags = flags;
+ return Ok(())
+ }
+ _ => return self.err(format!(
+ "Unrecognized flag '{}'.", self.cur()).as_slice()),
+ }
+ }
+ }
+
+ // Peeks at the next character and returns whether it's ungreedy or not.
+ // If it is, then the next character is consumed.
+ fn get_next_greedy(&mut self) -> Result<Greed, Error> {
+ Ok(if self.peek_is(1, '?') {
+ try!(self.expect('?'))
+ Ungreedy
+ } else {
+ Greedy
+ }.swap(self.flags & FLAG_SWAP_GREED > 0))
+ }
+
+ // Searches the stack (starting at the top) until it finds an expression
+ // for which `pred` returns true. The index of that expression in the
+ // stack is returned.
+ // If there's no match, then one of two things happens depending on the
+ // values of `allow_start`. When it's true, then `0` will be returned.
+ // Otherwise, an error will be returned.
+ // Generally, `allow_start` is only true when you're *not* expecting an
+ // opening parenthesis.
+ fn pos_last(&self, allow_start: bool, pred: |&BuildAst| -> bool)
+ -> Result<uint, Error> {
+ let from = match self.stack.iter().rev().position(pred) {
+ Some(i) => i,
+ None => {
+ if allow_start {
+ self.stack.len()
+ } else {
+ return self.err("No matching opening parenthesis.")
+ }
+ }
+ };
+ // Adjust index since 'from' is for the reversed stack.
+ // Also, don't include the '(' or '|'.
+ Ok(self.stack.len() - from)
+ }
+
+ // concat starts at `from` in the parser's stack and concatenates all
+ // expressions up to the top of the stack. The resulting concatenation is
+ // then pushed on to the stack.
+ // Usually `from` corresponds to the position of an opening parenthesis,
+ // a '|' (alternation) or the start of the entire expression.
+ fn concat(&mut self, from: uint) -> Result<(), Error> {
+ let ast = try!(self.build_from(from, concat_flatten));
+ self.push(ast);
+ Ok(())
+ }
+
+ // concat starts at `from` in the parser's stack and alternates all
+ // expressions up to the top of the stack. The resulting alternation is
+ // then pushed on to the stack.
+ // Usually `from` corresponds to the position of an opening parenthesis
+ // or the start of the entire expression.
+ // This will also drop any opening parens or alternation bars found in
+ // the intermediate AST.
+ fn alternate(&mut self, mut from: uint) -> Result<(), Error> {
+ // Unlike in the concatenation case, we want 'build_from' to continue
+ // all the way to the opening left paren (so it will be popped off and
+ // thrown away). But be careful with overflow---we can't count on the
+ // open paren to be there.
+ if from > 0 { from = from - 1}
+ let ast = try!(self.build_from(from, |l,r| Alt(box l, box r)));
+ self.push(ast);
+ Ok(())
+ }
+
+ // build_from combines all AST elements starting at 'from' in the
+ // parser's stack using 'mk' to combine them. If any such element is not an
+ // AST then it is popped off the stack and ignored.
+ fn build_from(&mut self, from: uint, mk: |Ast, Ast| -> Ast)
+ -> Result<Ast, Error> {
+ if from >= self.stack.len() {
+ return self.err("Empty group or alternate not allowed.")
+ }
+
+ let mut combined = try!(self.pop_ast());
+ let mut i = self.stack.len();
+ while i > from {
+ i = i - 1;
+ match self.stack.pop().unwrap() {
+ Ast(x) => combined = mk(x, combined),
+ _ => {},
+ }
+ }
+ Ok(combined)
+ }
+
+ fn parse_uint(&self, s: &str) -> Result<uint, Error> {
+ match from_str::<uint>(s) {
+ Some(i) => Ok(i),
+ None => {
+ self.err(format!("Expected an unsigned integer but got '{}'.",
+ s).as_slice())
+ }
+ }
+ }
+
+ fn char_from_u32(&self, n: u32) -> Result<char, Error> {
+ match char::from_u32(n) {
+ Some(c) => Ok(c),
+ None => {
+ self.err(format!("Could not decode '{}' to unicode \
+ character.",
+ n).as_slice())
+ }
+ }
+ }
+
+ fn pos(&self, c: char) -> Option<uint> {
+ self.chars.iter()
+ .skip(self.chari).position(|&c2| c2 == c).map(|i| self.chari + i)
+ }
+
+ fn err<T>(&self, msg: &str) -> Result<T, Error> {
+ Err(Error {
+ pos: self.chari,
+ msg: msg.to_string(),
+ })
+ }
+
+ fn peek(&self, offset: uint) -> Option<char> {
+ if self.chari + offset >= self.chars.len() {
+ return None
+ }
+ Some(*self.chars.get(self.chari + offset))
+ }
+
+ fn peek_is(&self, offset: uint, is: char) -> bool {
+ self.peek(offset) == Some(is)
+ }
+
+ fn cur(&self) -> char {
+ *self.chars.get(self.chari)
+ }
+
+ fn slice(&self, start: uint, end: uint) -> String {
+ str::from_chars(self.chars.as_slice().slice(start, end)).to_string()
+ }
+}
+
+// Given an unordered collection of character ranges, combine_ranges returns
+// an ordered sequence of character ranges where no two ranges overlap. They
+// are ordered from least to greatest (using start position).
+fn combine_ranges(unordered: Vec<(char, char)>) -> Vec<(char, char)> {
+ // Returns true iff the two character classes overlap or share a boundary.
+ // e.g., ('a', 'g') and ('h', 'm') would return true.
+ fn should_merge((a, b): (char, char), (x, y): (char, char)) -> bool {
+ cmp::max(a, x) as u32 <= cmp::min(b, y) as u32 + 1
+ }
+
+ // This is currently O(n^2), but I think with sufficient cleverness,
+ // it can be reduced to O(n) **if necessary**.
+ let mut ordered: Vec<(char, char)> = Vec::with_capacity(unordered.len());
+ for (us, ue) in unordered.move_iter() {
+ let (mut us, mut ue) = (us, ue);
+ assert!(us <= ue);
+ let mut which: Option<uint> = None;
+ for (i, &(os, oe)) in ordered.iter().enumerate() {
+ if should_merge((us, ue), (os, oe)) {
+ us = cmp::min(us, os);
+ ue = cmp::max(ue, oe);
+ which = Some(i);
+ break
+ }
+ }
+ match which {
+ None => ordered.push((us, ue)),
+ Some(i) => *ordered.get_mut(i) = (us, ue),
+ }
+ }
+ ordered.sort();
+ ordered
+}
+
+// Constructs a Unicode friendly Perl character class from \d, \s or \w
+// (or any of their negated forms). Note that this does not handle negation.
+fn perl_unicode_class(which: char) -> Vec<(char, char)> {
+ match which.to_lowercase() {
+ 'd' => Vec::from_slice(PERLD),
+ 's' => Vec::from_slice(PERLS),
+ 'w' => Vec::from_slice(PERLW),
+ _ => unreachable!(),
+ }
+}
+
+// Returns a concatenation of two expressions. This also guarantees that a
+// `Cat` expression will never be a direct child of another `Cat` expression.
+fn concat_flatten(x: Ast, y: Ast) -> Ast {
+ match (x, y) {
+ (Cat(mut xs), Cat(ys)) => { xs.push_all_move(ys); Cat(xs) }
+ (Cat(mut xs), ast) => { xs.push(ast); Cat(xs) }
+ (ast, Cat(mut xs)) => { xs.unshift(ast); Cat(xs) }
+ (ast1, ast2) => Cat(vec!(ast1, ast2)),
+ }
+}
+
+pub fn is_punct(c: char) -> bool {
+ match c {
+ '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' |
+ '[' | ']' | '{' | '}' | '^' | '$' => true,
+ _ => false,
+ }
+}
+
+fn is_valid_cap(c: char) -> bool {
+ c == '_' || (c >= '0' && c <= '9')
+ || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
+}
+
+fn find_class(classes: NamedClasses, name: &str) -> Option<Vec<(char, char)>> {
+ match classes.bsearch(|&(s, _)| s.cmp(&name)) {
+ Some(i) => Some(Vec::from_slice(classes[i].val1())),
+ None => None,
+ }
+}
+
+type Class = &'static [(char, char)];
+type NamedClasses = &'static [(&'static str, Class)];
+
+static ASCII_CLASSES: NamedClasses = &[
+ // Classes must be in alphabetical order so that bsearch works.
+ // [:alnum:] alphanumeric (== [0-9A-Za-z])
+ // [:alpha:] alphabetic (== [A-Za-z])
+ // [:ascii:] ASCII (== [\x00-\x7F])
+ // [:blank:] blank (== [\t ])
+ // [:cntrl:] control (== [\x00-\x1F\x7F])
+ // [:digit:] digits (== [0-9])
+ // [:graph:] graphical (== [!-~])
+ // [:lower:] lower case (== [a-z])
+ // [:print:] printable (== [ -~] == [ [:graph:]])
+ // [:punct:] punctuation (== [!-/:-@[-`{-~])
+ // [:space:] whitespace (== [\t\n\v\f\r ])
+ // [:upper:] upper case (== [A-Z])
+ // [:word:] word characters (== [0-9A-Za-z_])
+ // [:xdigit:] hex digit (== [0-9A-Fa-f])
+ // Taken from: http://golang.org/pkg/regex/syntax/
+ ("alnum", &[('0', '9'), ('A', 'Z'), ('a', 'z')]),
+ ("alpha", &[('A', 'Z'), ('a', 'z')]),
+ ("ascii", &[('\x00', '\x7F')]),
+ ("blank", &[(' ', ' '), ('\t', '\t')]),
+ ("cntrl", &[('\x00', '\x1F'), ('\x7F', '\x7F')]),
+ ("digit", &[('0', '9')]),
+ ("graph", &[('!', '~')]),
+ ("lower", &[('a', 'z')]),
+ ("print", &[(' ', '~')]),
+ ("punct", &[('!', '/'), (':', '@'), ('[', '`'), ('{', '~')]),
+ ("space", &[('\t', '\t'), ('\n', '\n'), ('\x0B', '\x0B'), ('\x0C', '\x0C'),
+ ('\r', '\r'), (' ', ' ')]),
+ ("upper", &[('A', 'Z')]),
+ ("word", &[('0', '9'), ('A', 'Z'), ('a', 'z'), ('_', '_')]),
+ ("xdigit", &[('0', '9'), ('A', 'F'), ('a', 'f')]),
+];
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::char;
-use std::cmp;
-use std::fmt;
-use std::iter;
-use std::num;
-use std::str;
-
-/// Static data containing Unicode ranges for general categories and scripts.
-use self::unicode::{UNICODE_CLASSES, PERLD, PERLS, PERLW};
-#[allow(visible_private_types)]
-pub mod unicode;
-
-/// The maximum number of repetitions allowed with the `{n,m}` syntax.
-static MAX_REPEAT: uint = 1000;
-
-/// Error corresponds to something that can go wrong while parsing
-/// a regular expression.
-///
-/// (Once an expression is compiled, it is not possible to produce an error
-/// via searching, splitting or replacing.)
-pub struct Error {
- /// The *approximate* character index of where the error occurred.
- pub pos: uint,
- /// A message describing the error.
- pub msg: String,
-}
-
-impl fmt::Show for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "Regex syntax error near position {}: {}",
- self.pos, self.msg)
- }
-}
-
-/// Represents the abstract syntax of a regular expression.
-/// It is showable so that error messages resulting from a bug can provide
-/// useful information.
-/// It is cloneable so that expressions can be repeated for the counted
-/// repetition feature. (No other copying is done.)
-///
-/// Note that this representation prevents one from reproducing the regex as
-/// it was typed. (But it could be used to reproduce an equivalent regex.)
-#[deriving(Show, Clone)]
-pub enum Ast {
- Nothing,
- Literal(char, Flags),
- Dot(Flags),
- Class(Vec<(char, char)>, Flags),
- Begin(Flags),
- End(Flags),
- WordBoundary(Flags),
- Capture(uint, Option<String>, Box<Ast>),
- // Represent concatenation as a flat vector to avoid blowing the
- // stack in the compiler.
- Cat(Vec<Ast>),
- Alt(Box<Ast>, Box<Ast>),
- Rep(Box<Ast>, Repeater, Greed),
-}
-
-#[deriving(Show, PartialEq, Clone)]
-pub enum Repeater {
- ZeroOne,
- ZeroMore,
- OneMore,
-}
-
-#[deriving(Show, Clone)]
-pub enum Greed {
- Greedy,
- Ungreedy,
-}
-
-impl Greed {
- pub fn is_greedy(&self) -> bool {
- match *self {
- Greedy => true,
- _ => false,
- }
- }
-
- fn swap(self, swapped: bool) -> Greed {
- if !swapped { return self }
- match self {
- Greedy => Ungreedy,
- Ungreedy => Greedy,
- }
- }
-}
-
-/// BuildAst is a regrettable type that represents intermediate state for
-/// constructing an abstract syntax tree. Its central purpose is to facilitate
-/// parsing groups and alternations while also maintaining a stack of flag
-/// state.
-#[deriving(Show)]
-enum BuildAst {
- Ast(Ast),
- Paren(Flags, uint, String), // '('
- Bar, // '|'
-}
-
-impl BuildAst {
- fn paren(&self) -> bool {
- match *self {
- Paren(_, _, _) => true,
- _ => false,
- }
- }
-
- fn flags(&self) -> Flags {
- match *self {
- Paren(flags, _, _) => flags,
- _ => fail!("Cannot get flags from {}", self),
- }
- }
-
- fn capture(&self) -> Option<uint> {
- match *self {
- Paren(_, 0, _) => None,
- Paren(_, c, _) => Some(c),
- _ => fail!("Cannot get capture group from {}", self),
- }
- }
-
- fn capture_name(&self) -> Option<String> {
- match *self {
- Paren(_, 0, _) => None,
- Paren(_, _, ref name) => {
- if name.len() == 0 {
- None
- } else {
- Some(name.clone())
- }
- }
- _ => fail!("Cannot get capture name from {}", self),
- }
- }
-
- fn bar(&self) -> bool {
- match *self {
- Bar => true,
- _ => false,
- }
- }
-
- fn unwrap(self) -> Result<Ast, Error> {
- match self {
- Ast(x) => Ok(x),
- _ => fail!("Tried to unwrap non-AST item: {}", self),
- }
- }
-}
-
-/// Flags represents all options that can be twiddled by a user in an
-/// expression.
-pub type Flags = u8;
-
-pub static FLAG_EMPTY: u8 = 0;
-pub static FLAG_NOCASE: u8 = 1 << 0; // i
-pub static FLAG_MULTI: u8 = 1 << 1; // m
-pub static FLAG_DOTNL: u8 = 1 << 2; // s
-pub static FLAG_SWAP_GREED: u8 = 1 << 3; // U
-pub static FLAG_NEGATED: u8 = 1 << 4; // char class or not word boundary
-
-struct Parser<'a> {
- // The input, parsed only as a sequence of UTF8 code points.
- chars: Vec<char>,
- // The index of the current character in the input.
- chari: uint,
- // The intermediate state representing the AST.
- stack: Vec<BuildAst>,
- // The current set of flags.
- flags: Flags,
- // The total number of capture groups.
- // Incremented each time an opening left paren is seen (assuming it is
- // opening a capture group).
- caps: uint,
- // A set of all capture group names used only to detect duplicates.
- names: Vec<String>,
-}
-
-pub fn parse(s: &str) -> Result<Ast, Error> {
- Parser {
- chars: s.chars().collect(),
- chari: 0,
- stack: vec!(),
- flags: FLAG_EMPTY,
- caps: 0,
- names: vec!(),
- }.parse()
-}
-
-impl<'a> Parser<'a> {
- fn parse(&mut self) -> Result<Ast, Error> {
- if self.chars.len() == 0 {
- return Ok(Nothing);
- }
- loop {
- let c = self.cur();
- match c {
- '?' | '*' | '+' => try!(self.push_repeater(c)),
- '\\' => {
- let ast = try!(self.parse_escape());
- self.push(ast)
- }
- '{' => try!(self.parse_counted()),
- '[' => match self.try_parse_ascii() {
- None => try!(self.parse_class()),
- Some(class) => self.push(class),
- },
- '(' => {
- if self.peek_is(1, '?') {
- try!(self.expect('?'))
- try!(self.parse_group_opts())
- } else {
- self.caps += 1;
- self.stack.push(Paren(self.flags,
- self.caps,
- "".to_string()))
- }
- }
- ')' => {
- let catfrom = try!(
- self.pos_last(false, |x| x.paren() || x.bar()));
- try!(self.concat(catfrom));
-
- let altfrom = try!(self.pos_last(false, |x| x.paren()));
- // Before we smush the alternates together and pop off the
- // left paren, let's grab the old flags and see if we
- // need a capture.
- let (cap, cap_name, oldflags) = {
- let paren = self.stack.get(altfrom-1);
- (paren.capture(), paren.capture_name(), paren.flags())
- };
- try!(self.alternate(altfrom));
- self.flags = oldflags;
-
- // If this was a capture, pop what we just pushed in
- // alternate and make it a capture.
- if cap.is_some() {
- let ast = try!(self.pop_ast());
- self.push(Capture(cap.unwrap(), cap_name, box ast));
- }
- }
- '|' => {
- let catfrom = try!(
- self.pos_last(true, |x| x.paren() || x.bar()));
- try!(self.concat(catfrom));
-
- self.stack.push(Bar);
- }
- _ => try!(self.push_literal(c)),
- }
- if !self.next_char() {
- break
- }
- }
-
- // Try to improve error handling. At this point, there should be
- // no remaining open parens.
- if self.stack.iter().any(|x| x.paren()) {
- return self.err("Unclosed parenthesis.")
- }
- let catfrom = try!(self.pos_last(true, |x| x.bar()));
- try!(self.concat(catfrom));
- try!(self.alternate(0));
-
- assert!(self.stack.len() == 1);
- self.pop_ast()
- }
-
- fn noteof(&mut self, expected: &str) -> Result<(), Error> {
- match self.next_char() {
- true => Ok(()),
- false => {
- self.err(format!("Expected {} but got EOF.",
- expected).as_slice())
- }
- }
- }
-
- fn expect(&mut self, expected: char) -> Result<(), Error> {
- match self.next_char() {
- true if self.cur() == expected => Ok(()),
- true => self.err(format!("Expected '{}' but got '{}'.",
- expected, self.cur()).as_slice()),
- false => {
- self.err(format!("Expected '{}' but got EOF.",
- expected).as_slice())
- }
- }
- }
-
- fn next_char(&mut self) -> bool {
- self.chari += 1;
- self.chari < self.chars.len()
- }
-
- fn pop_ast(&mut self) -> Result<Ast, Error> {
- match self.stack.pop().unwrap().unwrap() {
- Err(e) => Err(e),
- Ok(ast) => Ok(ast),
- }
- }
-
- fn push(&mut self, ast: Ast) {
- self.stack.push(Ast(ast))
- }
-
- fn push_repeater(&mut self, c: char) -> Result<(), Error> {
- if self.stack.len() == 0 {
- return self.err(
- "A repeat operator must be preceded by a valid expression.")
- }
- let rep: Repeater = match c {
- '?' => ZeroOne, '*' => ZeroMore, '+' => OneMore,
- _ => fail!("Not a valid repeater operator."),
- };
-
- match self.peek(1) {
- Some('*') | Some('+') =>
- return self.err(
- "Double repeat operators are not supported."),
- _ => {},
- }
- let ast = try!(self.pop_ast());
- match ast {
- Begin(_) | End(_) | WordBoundary(_) =>
- return self.err(
- "Repeat arguments cannot be empty width assertions."),
- _ => {}
- }
- let greed = try!(self.get_next_greedy());
- self.push(Rep(box ast, rep, greed));
- Ok(())
- }
-
- fn push_literal(&mut self, c: char) -> Result<(), Error> {
- let flags = self.flags;
- match c {
- '.' => {
- self.push(Dot(flags))
- }
- '^' => {
- self.push(Begin(flags))
- }
- '$' => {
- self.push(End(flags))
- }
- _ => {
- self.push(Literal(c, flags))
- }
- }
- Ok(())
- }
-
- // Parses all forms of character classes.
- // Assumes that '[' is the current character.
- fn parse_class(&mut self) -> Result<(), Error> {
- let negated =
- if self.peek_is(1, '^') {
- try!(self.expect('^'))
- FLAG_NEGATED
- } else {
- FLAG_EMPTY
- };
- let mut ranges: Vec<(char, char)> = vec!();
- let mut alts: Vec<Ast> = vec!();
-
- if self.peek_is(1, ']') {
- try!(self.expect(']'))
- ranges.push((']', ']'))
- }
- while self.peek_is(1, '-') {
- try!(self.expect('-'))
- ranges.push(('-', '-'))
- }
- loop {
- try!(self.noteof("a closing ']' or a non-empty character class)"))
- let mut c = self.cur();
- match c {
- '[' =>
- match self.try_parse_ascii() {
- Some(Class(asciis, flags)) => {
- alts.push(Class(asciis, flags ^ negated));
- continue
- }
- Some(ast) =>
- fail!("Expected Class AST but got '{}'", ast),
- // Just drop down and try to add as a regular character.
- None => {},
- },
- '\\' => {
- match try!(self.parse_escape()) {
- Class(asciis, flags) => {
- alts.push(Class(asciis, flags ^ negated));
- continue
- }
- Literal(c2, _) => c = c2, // process below
- Begin(_) | End(_) | WordBoundary(_) =>
- return self.err(
- "\\A, \\z, \\b and \\B are not valid escape \
- sequences inside a character class."),
- ast => fail!("Unexpected AST item '{}'", ast),
- }
- }
- _ => {},
- }
- match c {
- ']' => {
- if ranges.len() > 0 {
- let flags = negated | (self.flags & FLAG_NOCASE);
- let mut ast = Class(combine_ranges(ranges), flags);
- for alt in alts.move_iter() {
- ast = Alt(box alt, box ast)
- }
- self.push(ast);
- } else if alts.len() > 0 {
- let mut ast = alts.pop().unwrap();
- for alt in alts.move_iter() {
- ast = Alt(box alt, box ast)
- }
- self.push(ast);
- }
- return Ok(())
- }
- c => {
- if self.peek_is(1, '-') && !self.peek_is(2, ']') {
- try!(self.expect('-'))
- try!(self.noteof("not a ']'"))
- let c2 = self.cur();
- if c2 < c {
- return self.err(format!("Invalid character class \
- range '{}-{}'",
- c,
- c2).as_slice())
- }
- ranges.push((c, self.cur()))
- } else {
- ranges.push((c, c))
- }
- }
- }
- }
- }
-
- // Tries to parse an ASCII character class of the form [:name:].
- // If successful, returns an AST character class corresponding to name
- // and moves the parser to the final ']' character.
- // If unsuccessful, no state is changed and None is returned.
- // Assumes that '[' is the current character.
- fn try_parse_ascii(&mut self) -> Option<Ast> {
- if !self.peek_is(1, ':') {
- return None
- }
- let closer =
- match self.pos(']') {
- Some(i) => i,
- None => return None,
- };
- if *self.chars.get(closer-1) != ':' {
- return None
- }
- if closer - self.chari <= 3 {
- return None
- }
- let mut name_start = self.chari + 2;
- let negated =
- if self.peek_is(2, '^') {
- name_start += 1;
- FLAG_NEGATED
- } else {
- FLAG_EMPTY
- };
- let name = self.slice(name_start, closer - 1);
- match find_class(ASCII_CLASSES, name.as_slice()) {
- None => None,
- Some(ranges) => {
- self.chari = closer;
- let flags = negated | (self.flags & FLAG_NOCASE);
- Some(Class(combine_ranges(ranges), flags))
- }
- }
- }
-
- // Parses counted repetition. Supports:
- // {n}, {n,}, {n,m}, {n}?, {n,}? and {n,m}?
- // Assumes that '{' is the current character.
- // Returns either an error or moves the parser to the final '}' character.
- // (Or the '?' character if not greedy.)
- fn parse_counted(&mut self) -> Result<(), Error> {
- // Scan until the closing '}' and grab the stuff in {}.
- let start = self.chari;
- let closer =
- match self.pos('}') {
- Some(i) => i,
- None => {
- return self.err(format!("No closing brace for counted \
- repetition starting at position \
- {}.",
- start).as_slice())
- }
- };
- self.chari = closer;
- let greed = try!(self.get_next_greedy());
- let inner = str::from_chars(
- self.chars.as_slice().slice(start + 1, closer));
-
- // Parse the min and max values from the regex.
- let (mut min, mut max): (uint, Option<uint>);
- if !inner.as_slice().contains(",") {
- min = try!(self.parse_uint(inner.as_slice()));
- max = Some(min);
- } else {
- let pieces: Vec<&str> = inner.as_slice().splitn(',', 1).collect();
- let (smin, smax) = (*pieces.get(0), *pieces.get(1));
- if smin.len() == 0 {
- return self.err("Max repetitions cannot be specified \
- without min repetitions.")
- }
- min = try!(self.parse_uint(smin));
- max =
- if smax.len() == 0 {
- None
- } else {
- Some(try!(self.parse_uint(smax)))
- };
- }
-
- // Do some bounds checking and make sure max >= min.
- if min > MAX_REPEAT {
- return self.err(format!(
- "{} exceeds maximum allowed repetitions ({})",
- min, MAX_REPEAT).as_slice());
- }
- if max.is_some() {
- let m = max.unwrap();
- if m > MAX_REPEAT {
- return self.err(format!(
- "{} exceeds maximum allowed repetitions ({})",
- m, MAX_REPEAT).as_slice());
- }
- if m < min {
- return self.err(format!(
- "Max repetitions ({}) cannot be smaller than min \
- repetitions ({}).", m, min).as_slice());
- }
- }
-
- // Now manipulate the AST be repeating elements.
- if max.is_none() {
- // Require N copies of what's on the stack and then repeat it.
- let ast = try!(self.pop_ast());
- for _ in iter::range(0, min) {
- self.push(ast.clone())
- }
- self.push(Rep(box ast, ZeroMore, greed));
- } else {
- // Require N copies of what's on the stack and then repeat it
- // up to M times optionally.
- let ast = try!(self.pop_ast());
- for _ in iter::range(0, min) {
- self.push(ast.clone())
- }
- if max.is_some() {
- for _ in iter::range(min, max.unwrap()) {
- self.push(Rep(box ast.clone(), ZeroOne, greed))
- }
- }
- // It's possible that we popped something off the stack but
- // never put anything back on it. To keep things simple, add
- // a no-op expression.
- if min == 0 && (max.is_none() || max == Some(0)) {
- self.push(Nothing)
- }
- }
- Ok(())
- }
-
- // Parses all escape sequences.
- // Assumes that '\' is the current character.
- fn parse_escape(&mut self) -> Result<Ast, Error> {
- try!(self.noteof("an escape sequence following a '\\'"))
-
- let c = self.cur();
- if is_punct(c) {
- return Ok(Literal(c, FLAG_EMPTY))
- }
- match c {
- 'a' => Ok(Literal('\x07', FLAG_EMPTY)),
- 'f' => Ok(Literal('\x0C', FLAG_EMPTY)),
- 't' => Ok(Literal('\t', FLAG_EMPTY)),
- 'n' => Ok(Literal('\n', FLAG_EMPTY)),
- 'r' => Ok(Literal('\r', FLAG_EMPTY)),
- 'v' => Ok(Literal('\x0B', FLAG_EMPTY)),
- 'A' => Ok(Begin(FLAG_EMPTY)),
- 'z' => Ok(End(FLAG_EMPTY)),
- 'b' => Ok(WordBoundary(FLAG_EMPTY)),
- 'B' => Ok(WordBoundary(FLAG_NEGATED)),
- '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7' => Ok(try!(self.parse_octal())),
- 'x' => Ok(try!(self.parse_hex())),
- 'p' | 'P' => Ok(try!(self.parse_unicode_name())),
- 'd' | 'D' | 's' | 'S' | 'w' | 'W' => {
- let ranges = perl_unicode_class(c);
- let mut flags = self.flags & FLAG_NOCASE;
- if c.is_uppercase() { flags |= FLAG_NEGATED }
- Ok(Class(ranges, flags))
- }
- _ => {
- self.err(format!("Invalid escape sequence '\\\\{}'",
- c).as_slice())
- }
- }
- }
-
- // Parses a unicode character class name, either of the form \pF where
- // F is a one letter unicode class name or of the form \p{name} where
- // name is the unicode class name.
- // Assumes that \p or \P has been read (and 'p' or 'P' is the current
- // character).
- fn parse_unicode_name(&mut self) -> Result<Ast, Error> {
- let negated = if self.cur() == 'P' { FLAG_NEGATED } else { FLAG_EMPTY };
- let mut name: String;
- if self.peek_is(1, '{') {
- try!(self.expect('{'))
- let closer =
- match self.pos('}') {
- Some(i) => i,
- None => return self.err(format!(
- "Missing '}}' for unclosed '{{' at position {}",
- self.chari).as_slice()),
- };
- if closer - self.chari + 1 == 0 {
- return self.err("No Unicode class name found.")
- }
- name = self.slice(self.chari + 1, closer);
- self.chari = closer;
- } else {
- if self.chari + 1 >= self.chars.len() {
- return self.err("No single letter Unicode class name found.")
- }
- name = self.slice(self.chari + 1, self.chari + 2);
- self.chari += 1;
- }
- match find_class(UNICODE_CLASSES, name.as_slice()) {
- None => {
- return self.err(format!("Could not find Unicode class '{}'",
- name).as_slice())
- }
- Some(ranges) => {
- Ok(Class(ranges, negated | (self.flags & FLAG_NOCASE)))
- }
- }
- }
-
- // Parses an octal number, up to 3 digits.
- // Assumes that \n has been read, where n is the first digit.
- fn parse_octal(&mut self) -> Result<Ast, Error> {
- let start = self.chari;
- let mut end = start + 1;
- let (d2, d3) = (self.peek(1), self.peek(2));
- if d2 >= Some('0') && d2 <= Some('7') {
- try!(self.noteof("expected octal character in [0-7]"))
- end += 1;
- if d3 >= Some('0') && d3 <= Some('7') {
- try!(self.noteof("expected octal character in [0-7]"))
- end += 1;
- }
- }
- let s = self.slice(start, end);
- match num::from_str_radix::<u32>(s.as_slice(), 8) {
- Some(n) => Ok(Literal(try!(self.char_from_u32(n)), FLAG_EMPTY)),
- None => {
- self.err(format!("Could not parse '{}' as octal number.",
- s).as_slice())
- }
- }
- }
-
- // Parse a hex number. Either exactly two digits or anything in {}.
- // Assumes that \x has been read.
- fn parse_hex(&mut self) -> Result<Ast, Error> {
- if !self.peek_is(1, '{') {
- try!(self.expect('{'))
- return self.parse_hex_two()
- }
- let start = self.chari + 2;
- let closer =
- match self.pos('}') {
- None => {
- return self.err(format!("Missing '}}' for unclosed \
- '{{' at position {}",
- start).as_slice())
- }
- Some(i) => i,
- };
- self.chari = closer;
- self.parse_hex_digits(self.slice(start, closer).as_slice())
- }
-
- // Parses a two-digit hex number.
- // Assumes that \xn has been read, where n is the first digit and is the
- // current character.
- // After return, parser will point at the second digit.
- fn parse_hex_two(&mut self) -> Result<Ast, Error> {
- let (start, end) = (self.chari, self.chari + 2);
- let bad = self.slice(start - 2, self.chars.len());
- try!(self.noteof(format!("Invalid hex escape sequence '{}'",
- bad).as_slice()))
- self.parse_hex_digits(self.slice(start, end).as_slice())
- }
-
- // Parses `s` as a hexadecimal number.
- fn parse_hex_digits(&self, s: &str) -> Result<Ast, Error> {
- match num::from_str_radix::<u32>(s, 16) {
- Some(n) => Ok(Literal(try!(self.char_from_u32(n)), FLAG_EMPTY)),
- None => {
- self.err(format!("Could not parse '{}' as hex number.",
- s).as_slice())
- }
- }
- }
-
- // Parses a named capture.
- // Assumes that '(?P<' has been consumed and that the current character
- // is '<'.
- // When done, parser will be at the closing '>' character.
- fn parse_named_capture(&mut self) -> Result<(), Error> {
- try!(self.noteof("a capture name"))
- let closer =
- match self.pos('>') {
- Some(i) => i,
- None => return self.err("Capture name must end with '>'."),
- };
- if closer - self.chari == 0 {
- return self.err("Capture names must have at least 1 character.")
- }
- let name = self.slice(self.chari, closer);
- if !name.as_slice().chars().all(is_valid_cap) {
- return self.err(
- "Capture names can only have underscores, letters and digits.")
- }
- if self.names.contains(&name) {
- return self.err(format!("Duplicate capture group name '{}'.",
- name).as_slice())
- }
- self.names.push(name.clone());
- self.chari = closer;
- self.caps += 1;
- self.stack.push(Paren(self.flags, self.caps, name));
- Ok(())
- }
-
- // Parses non-capture groups and options.
- // Assumes that '(?' has already been consumed and '?' is the current
- // character.
- fn parse_group_opts(&mut self) -> Result<(), Error> {
- if self.peek_is(1, 'P') && self.peek_is(2, '<') {
- try!(self.expect('P')) try!(self.expect('<'))
- return self.parse_named_capture()
- }
- let start = self.chari;
- let mut flags = self.flags;
- let mut sign = 1i;
- let mut saw_flag = false;
- loop {
- try!(self.noteof("expected non-empty set of flags or closing ')'"))
- match self.cur() {
- 'i' => { flags = flags | FLAG_NOCASE; saw_flag = true},
- 'm' => { flags = flags | FLAG_MULTI; saw_flag = true},
- 's' => { flags = flags | FLAG_DOTNL; saw_flag = true},
- 'U' => { flags = flags | FLAG_SWAP_GREED; saw_flag = true},
- '-' => {
- if sign < 0 {
- return self.err(format!(
- "Cannot negate flags twice in '{}'.",
- self.slice(start, self.chari + 1)).as_slice())
- }
- sign = -1;
- saw_flag = false;
- flags = flags ^ flags;
- }
- ':' | ')' => {
- if sign < 0 {
- if !saw_flag {
- return self.err(format!(
- "A valid flag does not follow negation in '{}'",
- self.slice(start, self.chari + 1)).as_slice())
- }
- flags = flags ^ flags;
- }
- if self.cur() == ':' {
- // Save the old flags with the opening paren.
- self.stack.push(Paren(self.flags, 0, "".to_string()));
- }
- self.flags = flags;
- return Ok(())
- }
- _ => return self.err(format!(
- "Unrecognized flag '{}'.", self.cur()).as_slice()),
- }
- }
- }
-
- // Peeks at the next character and returns whether it's ungreedy or not.
- // If it is, then the next character is consumed.
- fn get_next_greedy(&mut self) -> Result<Greed, Error> {
- Ok(if self.peek_is(1, '?') {
- try!(self.expect('?'))
- Ungreedy
- } else {
- Greedy
- }.swap(self.flags & FLAG_SWAP_GREED > 0))
- }
-
- // Searches the stack (starting at the top) until it finds an expression
- // for which `pred` returns true. The index of that expression in the
- // stack is returned.
- // If there's no match, then one of two things happens depending on the
- // values of `allow_start`. When it's true, then `0` will be returned.
- // Otherwise, an error will be returned.
- // Generally, `allow_start` is only true when you're *not* expecting an
- // opening parenthesis.
- fn pos_last(&self, allow_start: bool, pred: |&BuildAst| -> bool)
- -> Result<uint, Error> {
- let from = match self.stack.iter().rev().position(pred) {
- Some(i) => i,
- None => {
- if allow_start {
- self.stack.len()
- } else {
- return self.err("No matching opening parenthesis.")
- }
- }
- };
- // Adjust index since 'from' is for the reversed stack.
- // Also, don't include the '(' or '|'.
- Ok(self.stack.len() - from)
- }
-
- // concat starts at `from` in the parser's stack and concatenates all
- // expressions up to the top of the stack. The resulting concatenation is
- // then pushed on to the stack.
- // Usually `from` corresponds to the position of an opening parenthesis,
- // a '|' (alternation) or the start of the entire expression.
- fn concat(&mut self, from: uint) -> Result<(), Error> {
- let ast = try!(self.build_from(from, concat_flatten));
- self.push(ast);
- Ok(())
- }
-
- // concat starts at `from` in the parser's stack and alternates all
- // expressions up to the top of the stack. The resulting alternation is
- // then pushed on to the stack.
- // Usually `from` corresponds to the position of an opening parenthesis
- // or the start of the entire expression.
- // This will also drop any opening parens or alternation bars found in
- // the intermediate AST.
- fn alternate(&mut self, mut from: uint) -> Result<(), Error> {
- // Unlike in the concatenation case, we want 'build_from' to continue
- // all the way to the opening left paren (so it will be popped off and
- // thrown away). But be careful with overflow---we can't count on the
- // open paren to be there.
- if from > 0 { from = from - 1}
- let ast = try!(self.build_from(from, |l,r| Alt(box l, box r)));
- self.push(ast);
- Ok(())
- }
-
- // build_from combines all AST elements starting at 'from' in the
- // parser's stack using 'mk' to combine them. If any such element is not an
- // AST then it is popped off the stack and ignored.
- fn build_from(&mut self, from: uint, mk: |Ast, Ast| -> Ast)
- -> Result<Ast, Error> {
- if from >= self.stack.len() {
- return self.err("Empty group or alternate not allowed.")
- }
-
- let mut combined = try!(self.pop_ast());
- let mut i = self.stack.len();
- while i > from {
- i = i - 1;
- match self.stack.pop().unwrap() {
- Ast(x) => combined = mk(x, combined),
- _ => {},
- }
- }
- Ok(combined)
- }
-
- fn parse_uint(&self, s: &str) -> Result<uint, Error> {
- match from_str::<uint>(s) {
- Some(i) => Ok(i),
- None => {
- self.err(format!("Expected an unsigned integer but got '{}'.",
- s).as_slice())
- }
- }
- }
-
- fn char_from_u32(&self, n: u32) -> Result<char, Error> {
- match char::from_u32(n) {
- Some(c) => Ok(c),
- None => {
- self.err(format!("Could not decode '{}' to unicode \
- character.",
- n).as_slice())
- }
- }
- }
-
- fn pos(&self, c: char) -> Option<uint> {
- self.chars.iter()
- .skip(self.chari).position(|&c2| c2 == c).map(|i| self.chari + i)
- }
-
- fn err<T>(&self, msg: &str) -> Result<T, Error> {
- Err(Error {
- pos: self.chari,
- msg: msg.to_string(),
- })
- }
-
- fn peek(&self, offset: uint) -> Option<char> {
- if self.chari + offset >= self.chars.len() {
- return None
- }
- Some(*self.chars.get(self.chari + offset))
- }
-
- fn peek_is(&self, offset: uint, is: char) -> bool {
- self.peek(offset) == Some(is)
- }
-
- fn cur(&self) -> char {
- *self.chars.get(self.chari)
- }
-
- fn slice(&self, start: uint, end: uint) -> String {
- str::from_chars(self.chars.as_slice().slice(start, end)).to_string()
- }
-}
-
-// Given an unordered collection of character ranges, combine_ranges returns
-// an ordered sequence of character ranges where no two ranges overlap. They
-// are ordered from least to greatest (using start position).
-fn combine_ranges(unordered: Vec<(char, char)>) -> Vec<(char, char)> {
- // Returns true iff the two character classes overlap or share a boundary.
- // e.g., ('a', 'g') and ('h', 'm') would return true.
- fn should_merge((a, b): (char, char), (x, y): (char, char)) -> bool {
- cmp::max(a, x) as u32 <= cmp::min(b, y) as u32 + 1
- }
-
- // This is currently O(n^2), but I think with sufficient cleverness,
- // it can be reduced to O(n) **if necessary**.
- let mut ordered: Vec<(char, char)> = Vec::with_capacity(unordered.len());
- for (us, ue) in unordered.move_iter() {
- let (mut us, mut ue) = (us, ue);
- assert!(us <= ue);
- let mut which: Option<uint> = None;
- for (i, &(os, oe)) in ordered.iter().enumerate() {
- if should_merge((us, ue), (os, oe)) {
- us = cmp::min(us, os);
- ue = cmp::max(ue, oe);
- which = Some(i);
- break
- }
- }
- match which {
- None => ordered.push((us, ue)),
- Some(i) => *ordered.get_mut(i) = (us, ue),
- }
- }
- ordered.sort();
- ordered
-}
-
-// Constructs a Unicode friendly Perl character class from \d, \s or \w
-// (or any of their negated forms). Note that this does not handle negation.
-fn perl_unicode_class(which: char) -> Vec<(char, char)> {
- match which.to_lowercase() {
- 'd' => Vec::from_slice(PERLD),
- 's' => Vec::from_slice(PERLS),
- 'w' => Vec::from_slice(PERLW),
- _ => unreachable!(),
- }
-}
-
-// Returns a concatenation of two expressions. This also guarantees that a
-// `Cat` expression will never be a direct child of another `Cat` expression.
-fn concat_flatten(x: Ast, y: Ast) -> Ast {
- match (x, y) {
- (Cat(mut xs), Cat(ys)) => { xs.push_all_move(ys); Cat(xs) }
- (Cat(mut xs), ast) => { xs.push(ast); Cat(xs) }
- (ast, Cat(mut xs)) => { xs.unshift(ast); Cat(xs) }
- (ast1, ast2) => Cat(vec!(ast1, ast2)),
- }
-}
-
-pub fn is_punct(c: char) -> bool {
- match c {
- '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' |
- '[' | ']' | '{' | '}' | '^' | '$' => true,
- _ => false,
- }
-}
-
-fn is_valid_cap(c: char) -> bool {
- c == '_' || (c >= '0' && c <= '9')
- || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
-}
-
-fn find_class(classes: NamedClasses, name: &str) -> Option<Vec<(char, char)>> {
- match classes.bsearch(|&(s, _)| s.cmp(&name)) {
- Some(i) => Some(Vec::from_slice(classes[i].val1())),
- None => None,
- }
-}
-
-type Class = &'static [(char, char)];
-type NamedClasses = &'static [(&'static str, Class)];
-
-static ASCII_CLASSES: NamedClasses = &[
- // Classes must be in alphabetical order so that bsearch works.
- // [:alnum:] alphanumeric (== [0-9A-Za-z])
- // [:alpha:] alphabetic (== [A-Za-z])
- // [:ascii:] ASCII (== [\x00-\x7F])
- // [:blank:] blank (== [\t ])
- // [:cntrl:] control (== [\x00-\x1F\x7F])
- // [:digit:] digits (== [0-9])
- // [:graph:] graphical (== [!-~])
- // [:lower:] lower case (== [a-z])
- // [:print:] printable (== [ -~] == [ [:graph:]])
- // [:punct:] punctuation (== [!-/:-@[-`{-~])
- // [:space:] whitespace (== [\t\n\v\f\r ])
- // [:upper:] upper case (== [A-Z])
- // [:word:] word characters (== [0-9A-Za-z_])
- // [:xdigit:] hex digit (== [0-9A-Fa-f])
- // Taken from: http://golang.org/pkg/regex/syntax/
- ("alnum", &[('0', '9'), ('A', 'Z'), ('a', 'z')]),
- ("alpha", &[('A', 'Z'), ('a', 'z')]),
- ("ascii", &[('\x00', '\x7F')]),
- ("blank", &[(' ', ' '), ('\t', '\t')]),
- ("cntrl", &[('\x00', '\x1F'), ('\x7F', '\x7F')]),
- ("digit", &[('0', '9')]),
- ("graph", &[('!', '~')]),
- ("lower", &[('a', 'z')]),
- ("print", &[(' ', '~')]),
- ("punct", &[('!', '/'), (':', '@'), ('[', '`'), ('{', '~')]),
- ("space", &[('\t', '\t'), ('\n', '\n'), ('\x0B', '\x0B'), ('\x0C', '\x0C'),
- ('\r', '\r'), (' ', ' ')]),
- ("upper", &[('A', 'Z')]),
- ("word", &[('0', '9'), ('A', 'Z'), ('a', 'z'), ('_', '_')]),
- ("xdigit", &[('0', '9'), ('A', 'F'), ('a', 'f')]),
-];
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// DO NOT EDIT. Automatically generated by 'src/etc/regex-unicode-tables'
-// on 2014-04-23 00:13:04.445491.
-
-use parse::{Class, NamedClasses};
-
-pub static UNICODE_CLASSES: NamedClasses = &[
-
-("Arabic", &[
- ('\U00000600', '\U00000604'),
- ('\U00000606', '\U0000060b'),
- ('\U0000060d', '\U0000061a'),
- ('\U0000061c', '\U0000061c'),
- ('\U0000061e', '\U0000061e'),
- ('\U00000620', '\U0000063f'),
- ('\U00000641', '\U0000064a'),
- ('\U00000656', '\U0000065f'),
- ('\U0000066a', '\U0000066f'),
- ('\U00000671', '\U000006dc'),
- ('\U000006de', '\U000006ff'),
- ('\U00000750', '\U0000077f'),
- ('\U000008a0', '\U000008a0'),
- ('\U000008a2', '\U000008ac'),
- ('\U000008e4', '\U000008fe'),
- ('\U0000fb50', '\U0000fbc1'),
- ('\U0000fbd3', '\U0000fd3d'),
- ('\U0000fd50', '\U0000fd8f'),
- ('\U0000fd92', '\U0000fdc7'),
- ('\U0000fdf0', '\U0000fdfc'),
- ('\U0000fe70', '\U0000fe74'),
- ('\U0000fe76', '\U0000fefc'),
- ('\U00010e60', '\U00010e7e'),
- ('\U0001ee00', '\U0001ee03'),
- ('\U0001ee05', '\U0001ee1f'),
- ('\U0001ee21', '\U0001ee22'),
- ('\U0001ee24', '\U0001ee24'),
- ('\U0001ee27', '\U0001ee27'),
- ('\U0001ee29', '\U0001ee32'),
- ('\U0001ee34', '\U0001ee37'),
- ('\U0001ee39', '\U0001ee39'),
- ('\U0001ee3b', '\U0001ee3b'),
- ('\U0001ee42', '\U0001ee42'),
- ('\U0001ee47', '\U0001ee47'),
- ('\U0001ee49', '\U0001ee49'),
- ('\U0001ee4b', '\U0001ee4b'),
- ('\U0001ee4d', '\U0001ee4f'),
- ('\U0001ee51', '\U0001ee52'),
- ('\U0001ee54', '\U0001ee54'),
- ('\U0001ee57', '\U0001ee57'),
- ('\U0001ee59', '\U0001ee59'),
- ('\U0001ee5b', '\U0001ee5b'),
- ('\U0001ee5d', '\U0001ee5d'),
- ('\U0001ee5f', '\U0001ee5f'),
- ('\U0001ee61', '\U0001ee62'),
- ('\U0001ee64', '\U0001ee64'),
- ('\U0001ee67', '\U0001ee6a'),
- ('\U0001ee6c', '\U0001ee72'),
- ('\U0001ee74', '\U0001ee77'),
- ('\U0001ee79', '\U0001ee7c'),
- ('\U0001ee7e', '\U0001ee7e'),
- ('\U0001ee80', '\U0001ee89'),
- ('\U0001ee8b', '\U0001ee9b'),
- ('\U0001eea1', '\U0001eea3'),
- ('\U0001eea5', '\U0001eea9'),
- ('\U0001eeab', '\U0001eebb'),
- ('\U0001eef0', '\U0001eef1')
- ]),
-("Armenian", &[
- ('\U00000531', '\U00000556'),
- ('\U00000559', '\U0000055f'),
- ('\U00000561', '\U00000587'),
- ('\U0000058a', '\U0000058a'),
- ('\U0000058f', '\U0000058f'),
- ('\U0000fb13', '\U0000fb17')
- ]),
-("Avestan", &[
- ('\U00010b00', '\U00010b35'),
- ('\U00010b39', '\U00010b3f')
- ]),
-("Balinese", &[
- ('\U00001b00', '\U00001b4b'),
- ('\U00001b50', '\U00001b7c')
- ]),
-("Bamum", &[
- ('\U0000a6a0', '\U0000a6f7'),
- ('\U00016800', '\U00016a38')
- ]),
-("Batak", &[
- ('\U00001bc0', '\U00001bf3'),
- ('\U00001bfc', '\U00001bff')
- ]),
-("Bengali", &[
- ('\U00000981', '\U00000983'),
- ('\U00000985', '\U0000098c'),
- ('\U0000098f', '\U00000990'),
- ('\U00000993', '\U000009a8'),
- ('\U000009aa', '\U000009b0'),
- ('\U000009b2', '\U000009b2'),
- ('\U000009b6', '\U000009b9'),
- ('\U000009bc', '\U000009c4'),
- ('\U000009c7', '\U000009c8'),
- ('\U000009cb', '\U000009ce'),
- ('\U000009d7', '\U000009d7'),
- ('\U000009dc', '\U000009dd'),
- ('\U000009df', '\U000009e3'),
- ('\U000009e6', '\U000009fb')
- ]),
-("Bopomofo", &[
- ('\U000002ea', '\U000002eb'),
- ('\U00003105', '\U0000312d'),
- ('\U000031a0', '\U000031ba')
- ]),
-("Brahmi", &[
- ('\U00011000', '\U0001104d'),
- ('\U00011052', '\U0001106f')
- ]),
-("Braille", &[
- ('\U00002800', '\U000028ff')
- ]),
-("Buginese", &[
- ('\U00001a00', '\U00001a1b'),
- ('\U00001a1e', '\U00001a1f')
- ]),
-("Buhid", &[
- ('\U00001740', '\U00001753')
- ]),
-("C", &[
- ('\U00000000', '\U0000001f'),
- ('\U0000007f', '\U0000009f'),
- ('\U000000ad', '\U000000ad'),
- ('\U00000600', '\U00000604'),
- ('\U0000061c', '\U0000061c'),
- ('\U000006dd', '\U000006dd'),
- ('\U0000070f', '\U0000070f'),
- ('\U0000180e', '\U0000180e'),
- ('\U0000200b', '\U0000200f'),
- ('\U0000202a', '\U0000202e'),
- ('\U00002060', '\U00002064'),
- ('\U00002066', '\U0000206f'),
- ('\U0000e000', '\U0000e000'),
- ('\U0000f8ff', '\U0000f8ff'),
- ('\U0000feff', '\U0000feff'),
- ('\U0000fff9', '\U0000fffb'),
- ('\U000110bd', '\U000110bd'),
- ('\U0001d173', '\U0001d17a'),
- ('\U000e0001', '\U000e0001'),
- ('\U000e0020', '\U000e007f'),
- ('\U000f0000', '\U000f0000'),
- ('\U000ffffd', '\U000ffffd'),
- ('\U00100000', '\U00100000'),
- ('\U0010fffd', '\U0010fffd')
- ]),
-("Canadian_Aboriginal", &[
- ('\U00001400', '\U0000167f'),
- ('\U000018b0', '\U000018f5')
- ]),
-("Carian", &[
- ('\U000102a0', '\U000102d0')
- ]),
-("Cc", &[
- ('\U00000000', '\U0000001f'),
- ('\U0000007f', '\U0000009f')
- ]),
-("Cf", &[
- ('\U000000ad', '\U000000ad'),
- ('\U00000600', '\U00000604'),
- ('\U0000061c', '\U0000061c'),
- ('\U000006dd', '\U000006dd'),
- ('\U0000070f', '\U0000070f'),
- ('\U0000180e', '\U0000180e'),
- ('\U0000200b', '\U0000200f'),
- ('\U0000202a', '\U0000202e'),
- ('\U00002060', '\U00002064'),
- ('\U00002066', '\U0000206f'),
- ('\U0000feff', '\U0000feff'),
- ('\U0000fff9', '\U0000fffb'),
- ('\U000110bd', '\U000110bd'),
- ('\U0001d173', '\U0001d17a'),
- ('\U000e0001', '\U000e0001'),
- ('\U000e0020', '\U000e007f')
- ]),
-("Chakma", &[
- ('\U00011100', '\U00011134'),
- ('\U00011136', '\U00011143')
- ]),
-("Cham", &[
- ('\U0000aa00', '\U0000aa36'),
- ('\U0000aa40', '\U0000aa4d'),
- ('\U0000aa50', '\U0000aa59'),
- ('\U0000aa5c', '\U0000aa5f')
- ]),
-("Cherokee", &[
- ('\U000013a0', '\U000013f4')
- ]),
-("Co", &[
- ('\U0000e000', '\U0000e000'),
- ('\U0000f8ff', '\U0000f8ff'),
- ('\U000f0000', '\U000f0000'),
- ('\U000ffffd', '\U000ffffd'),
- ('\U00100000', '\U00100000'),
- ('\U0010fffd', '\U0010fffd')
- ]),
-("Common", &[
- ('\U00000000', '\U00000040'),
- ('\U0000005b', '\U00000060'),
- ('\U0000007b', '\U000000a9'),
- ('\U000000ab', '\U000000b9'),
- ('\U000000bb', '\U000000bf'),
- ('\U000000d7', '\U000000d7'),
- ('\U000000f7', '\U000000f7'),
- ('\U000002b9', '\U000002df'),
- ('\U000002e5', '\U000002e9'),
- ('\U000002ec', '\U000002ff'),
- ('\U00000374', '\U00000374'),
- ('\U0000037e', '\U0000037e'),
- ('\U00000385', '\U00000385'),
- ('\U00000387', '\U00000387'),
- ('\U00000589', '\U00000589'),
- ('\U0000060c', '\U0000060c'),
- ('\U0000061b', '\U0000061b'),
- ('\U0000061f', '\U0000061f'),
- ('\U00000640', '\U00000640'),
- ('\U00000660', '\U00000669'),
- ('\U000006dd', '\U000006dd'),
- ('\U00000964', '\U00000965'),
- ('\U00000e3f', '\U00000e3f'),
- ('\U00000fd5', '\U00000fd8'),
- ('\U000010fb', '\U000010fb'),
- ('\U000016eb', '\U000016ed'),
- ('\U00001735', '\U00001736'),
- ('\U00001802', '\U00001803'),
- ('\U00001805', '\U00001805'),
- ('\U00001cd3', '\U00001cd3'),
- ('\U00001ce1', '\U00001ce1'),
- ('\U00001ce9', '\U00001cec'),
- ('\U00001cee', '\U00001cf3'),
- ('\U00001cf5', '\U00001cf6'),
- ('\U00002000', '\U0000200b'),
- ('\U0000200e', '\U00002064'),
- ('\U00002066', '\U00002070'),
- ('\U00002074', '\U0000207e'),
- ('\U00002080', '\U0000208e'),
- ('\U000020a0', '\U000020ba'),
- ('\U00002100', '\U00002125'),
- ('\U00002127', '\U00002129'),
- ('\U0000212c', '\U00002131'),
- ('\U00002133', '\U0000214d'),
- ('\U0000214f', '\U0000215f'),
- ('\U00002189', '\U00002189'),
- ('\U00002190', '\U000023f3'),
- ('\U00002400', '\U00002426'),
- ('\U00002440', '\U0000244a'),
- ('\U00002460', '\U000026ff'),
- ('\U00002701', '\U000027ff'),
- ('\U00002900', '\U00002b4c'),
- ('\U00002b50', '\U00002b59'),
- ('\U00002e00', '\U00002e3b'),
- ('\U00002ff0', '\U00002ffb'),
- ('\U00003000', '\U00003004'),
- ('\U00003006', '\U00003006'),
- ('\U00003008', '\U00003020'),
- ('\U00003030', '\U00003037'),
- ('\U0000303c', '\U0000303f'),
- ('\U0000309b', '\U0000309c'),
- ('\U000030a0', '\U000030a0'),
- ('\U000030fb', '\U000030fc'),
- ('\U00003190', '\U0000319f'),
- ('\U000031c0', '\U000031e3'),
- ('\U00003220', '\U0000325f'),
- ('\U0000327f', '\U000032cf'),
- ('\U00003358', '\U000033ff'),
- ('\U00004dc0', '\U00004dff'),
- ('\U0000a700', '\U0000a721'),
- ('\U0000a788', '\U0000a78a'),
- ('\U0000a830', '\U0000a839'),
- ('\U0000a9cf', '\U0000a9cf'),
- ('\U0000fd3e', '\U0000fd3f'),
- ('\U0000fdfd', '\U0000fdfd'),
- ('\U0000fe10', '\U0000fe19'),
- ('\U0000fe30', '\U0000fe52'),
- ('\U0000fe54', '\U0000fe66'),
- ('\U0000fe68', '\U0000fe6b'),
- ('\U0000feff', '\U0000feff'),
- ('\U0000ff01', '\U0000ff20'),
- ('\U0000ff3b', '\U0000ff40'),
- ('\U0000ff5b', '\U0000ff65'),
- ('\U0000ff70', '\U0000ff70'),
- ('\U0000ff9e', '\U0000ff9f'),
- ('\U0000ffe0', '\U0000ffe6'),
- ('\U0000ffe8', '\U0000ffee'),
- ('\U0000fff9', '\U0000fffd'),
- ('\U00010100', '\U00010102'),
- ('\U00010107', '\U00010133'),
- ('\U00010137', '\U0001013f'),
- ('\U00010190', '\U0001019b'),
- ('\U000101d0', '\U000101fc'),
- ('\U0001d000', '\U0001d0f5'),
- ('\U0001d100', '\U0001d126'),
- ('\U0001d129', '\U0001d166'),
- ('\U0001d16a', '\U0001d17a'),
- ('\U0001d183', '\U0001d184'),
- ('\U0001d18c', '\U0001d1a9'),
- ('\U0001d1ae', '\U0001d1dd'),
- ('\U0001d300', '\U0001d356'),
- ('\U0001d360', '\U0001d371'),
- ('\U0001d400', '\U0001d454'),
- ('\U0001d456', '\U0001d49c'),
- ('\U0001d49e', '\U0001d49f'),
- ('\U0001d4a2', '\U0001d4a2'),
- ('\U0001d4a5', '\U0001d4a6'),
- ('\U0001d4a9', '\U0001d4ac'),
- ('\U0001d4ae', '\U0001d4b9'),
- ('\U0001d4bb', '\U0001d4bb'),
- ('\U0001d4bd', '\U0001d4c3'),
- ('\U0001d4c5', '\U0001d505'),
- ('\U0001d507', '\U0001d50a'),
- ('\U0001d50d', '\U0001d514'),
- ('\U0001d516', '\U0001d51c'),
- ('\U0001d51e', '\U0001d539'),
- ('\U0001d53b', '\U0001d53e'),
- ('\U0001d540', '\U0001d544'),
- ('\U0001d546', '\U0001d546'),
- ('\U0001d54a', '\U0001d550'),
- ('\U0001d552', '\U0001d6a5'),
- ('\U0001d6a8', '\U0001d7cb'),
- ('\U0001d7ce', '\U0001d7ff'),
- ('\U0001f000', '\U0001f02b'),
- ('\U0001f030', '\U0001f093'),
- ('\U0001f0a0', '\U0001f0ae'),
- ('\U0001f0b1', '\U0001f0be'),
- ('\U0001f0c1', '\U0001f0cf'),
- ('\U0001f0d1', '\U0001f0df'),
- ('\U0001f100', '\U0001f10a'),
- ('\U0001f110', '\U0001f12e'),
- ('\U0001f130', '\U0001f16b'),
- ('\U0001f170', '\U0001f19a'),
- ('\U0001f1e6', '\U0001f1ff'),
- ('\U0001f201', '\U0001f202'),
- ('\U0001f210', '\U0001f23a'),
- ('\U0001f240', '\U0001f248'),
- ('\U0001f250', '\U0001f251'),
- ('\U0001f300', '\U0001f320'),
- ('\U0001f330', '\U0001f335'),
- ('\U0001f337', '\U0001f37c'),
- ('\U0001f380', '\U0001f393'),
- ('\U0001f3a0', '\U0001f3c4'),
- ('\U0001f3c6', '\U0001f3ca'),
- ('\U0001f3e0', '\U0001f3f0'),
- ('\U0001f400', '\U0001f43e'),
- ('\U0001f440', '\U0001f440'),
- ('\U0001f442', '\U0001f4f7'),
- ('\U0001f4f9', '\U0001f4fc'),
- ('\U0001f500', '\U0001f53d'),
- ('\U0001f540', '\U0001f543'),
- ('\U0001f550', '\U0001f567'),
- ('\U0001f5fb', '\U0001f640'),
- ('\U0001f645', '\U0001f64f'),
- ('\U0001f680', '\U0001f6c5'),
- ('\U0001f700', '\U0001f773'),
- ('\U000e0001', '\U000e0001'),
- ('\U000e0020', '\U000e007f')
- ]),
-("Coptic", &[
- ('\U000003e2', '\U000003ef'),
- ('\U00002c80', '\U00002cf3'),
- ('\U00002cf9', '\U00002cff')
- ]),
-("Cuneiform", &[
- ('\U00012000', '\U0001236e'),
- ('\U00012400', '\U00012462'),
- ('\U00012470', '\U00012473')
- ]),
-("Cypriot", &[
- ('\U00010800', '\U00010805'),
- ('\U00010808', '\U00010808'),
- ('\U0001080a', '\U00010835'),
- ('\U00010837', '\U00010838'),
- ('\U0001083c', '\U0001083c'),
- ('\U0001083f', '\U0001083f')
- ]),
-("Cyrillic", &[
- ('\U00000400', '\U00000484'),
- ('\U00000487', '\U00000527'),
- ('\U00001d2b', '\U00001d2b'),
- ('\U00001d78', '\U00001d78'),
- ('\U00002de0', '\U00002dff'),
- ('\U0000a640', '\U0000a697'),
- ('\U0000a69f', '\U0000a69f')
- ]),
-("Deseret", &[
- ('\U00010400', '\U0001044f')
- ]),
-("Devanagari", &[
- ('\U00000900', '\U00000950'),
- ('\U00000953', '\U00000963'),
- ('\U00000966', '\U00000977'),
- ('\U00000979', '\U0000097f'),
- ('\U0000a8e0', '\U0000a8fb')
- ]),
-("Egyptian_Hieroglyphs", &[
- ('\U00013000', '\U0001342e')
- ]),
-("Ethiopic", &[
- ('\U00001200', '\U00001248'),
- ('\U0000124a', '\U0000124d'),
- ('\U00001250', '\U00001256'),
- ('\U00001258', '\U00001258'),
- ('\U0000125a', '\U0000125d'),
- ('\U00001260', '\U00001288'),
- ('\U0000128a', '\U0000128d'),
- ('\U00001290', '\U000012b0'),
- ('\U000012b2', '\U000012b5'),
- ('\U000012b8', '\U000012be'),
- ('\U000012c0', '\U000012c0'),
- ('\U000012c2', '\U000012c5'),
- ('\U000012c8', '\U000012d6'),
- ('\U000012d8', '\U00001310'),
- ('\U00001312', '\U00001315'),
- ('\U00001318', '\U0000135a'),
- ('\U0000135d', '\U0000137c'),
- ('\U00001380', '\U00001399'),
- ('\U00002d80', '\U00002d96'),
- ('\U00002da0', '\U00002da6'),
- ('\U00002da8', '\U00002dae'),
- ('\U00002db0', '\U00002db6'),
- ('\U00002db8', '\U00002dbe'),
- ('\U00002dc0', '\U00002dc6'),
- ('\U00002dc8', '\U00002dce'),
- ('\U00002dd0', '\U00002dd6'),
- ('\U00002dd8', '\U00002dde'),
- ('\U0000ab01', '\U0000ab06'),
- ('\U0000ab09', '\U0000ab0e'),
- ('\U0000ab11', '\U0000ab16'),
- ('\U0000ab20', '\U0000ab26'),
- ('\U0000ab28', '\U0000ab2e')
- ]),
-("Georgian", &[
- ('\U000010a0', '\U000010c5'),
- ('\U000010c7', '\U000010c7'),
- ('\U000010cd', '\U000010cd'),
- ('\U000010d0', '\U000010fa'),
- ('\U000010fc', '\U000010ff'),
- ('\U00002d00', '\U00002d25'),
- ('\U00002d27', '\U00002d27'),
- ('\U00002d2d', '\U00002d2d')
- ]),
-("Glagolitic", &[
- ('\U00002c00', '\U00002c2e'),
- ('\U00002c30', '\U00002c5e')
- ]),
-("Gothic", &[
- ('\U00010330', '\U0001034a')
- ]),
-("Greek", &[
- ('\U00000370', '\U00000373'),
- ('\U00000375', '\U00000377'),
- ('\U0000037a', '\U0000037d'),
- ('\U00000384', '\U00000384'),
- ('\U00000386', '\U00000386'),
- ('\U00000388', '\U0000038a'),
- ('\U0000038c', '\U0000038c'),
- ('\U0000038e', '\U000003a1'),
- ('\U000003a3', '\U000003e1'),
- ('\U000003f0', '\U000003ff'),
- ('\U00001d26', '\U00001d2a'),
- ('\U00001d5d', '\U00001d61'),
- ('\U00001d66', '\U00001d6a'),
- ('\U00001dbf', '\U00001dbf'),
- ('\U00001f00', '\U00001f15'),
- ('\U00001f18', '\U00001f1d'),
- ('\U00001f20', '\U00001f45'),
- ('\U00001f48', '\U00001f4d'),
- ('\U00001f50', '\U00001f57'),
- ('\U00001f59', '\U00001f59'),
- ('\U00001f5b', '\U00001f5b'),
- ('\U00001f5d', '\U00001f5d'),
- ('\U00001f5f', '\U00001f7d'),
- ('\U00001f80', '\U00001fb4'),
- ('\U00001fb6', '\U00001fc4'),
- ('\U00001fc6', '\U00001fd3'),
- ('\U00001fd6', '\U00001fdb'),
- ('\U00001fdd', '\U00001fef'),
- ('\U00001ff2', '\U00001ff4'),
- ('\U00001ff6', '\U00001ffe'),
- ('\U00002126', '\U00002126'),
- ('\U00010140', '\U0001018a'),
- ('\U0001d200', '\U0001d245')
- ]),
-("Gujarati", &[
- ('\U00000a81', '\U00000a83'),
- ('\U00000a85', '\U00000a8d'),
- ('\U00000a8f', '\U00000a91'),
- ('\U00000a93', '\U00000aa8'),
- ('\U00000aaa', '\U00000ab0'),
- ('\U00000ab2', '\U00000ab3'),
- ('\U00000ab5', '\U00000ab9'),
- ('\U00000abc', '\U00000ac5'),
- ('\U00000ac7', '\U00000ac9'),
- ('\U00000acb', '\U00000acd'),
- ('\U00000ad0', '\U00000ad0'),
- ('\U00000ae0', '\U00000ae3'),
- ('\U00000ae6', '\U00000af1')
- ]),
-("Gurmukhi", &[
- ('\U00000a01', '\U00000a03'),
- ('\U00000a05', '\U00000a0a'),
- ('\U00000a0f', '\U00000a10'),
- ('\U00000a13', '\U00000a28'),
- ('\U00000a2a', '\U00000a30'),
- ('\U00000a32', '\U00000a33'),
- ('\U00000a35', '\U00000a36'),
- ('\U00000a38', '\U00000a39'),
- ('\U00000a3c', '\U00000a3c'),
- ('\U00000a3e', '\U00000a42'),
- ('\U00000a47', '\U00000a48'),
- ('\U00000a4b', '\U00000a4d'),
- ('\U00000a51', '\U00000a51'),
- ('\U00000a59', '\U00000a5c'),
- ('\U00000a5e', '\U00000a5e'),
- ('\U00000a66', '\U00000a75')
- ]),
-("Han", &[
- ('\U00002e80', '\U00002e99'),
- ('\U00002e9b', '\U00002ef3'),
- ('\U00002f00', '\U00002fd5'),
- ('\U00003005', '\U00003005'),
- ('\U00003007', '\U00003007'),
- ('\U00003021', '\U00003029'),
- ('\U00003038', '\U0000303b'),
- ('\U00003400', '\U00004db5'),
- ('\U00004e00', '\U00009fcc'),
- ('\U0000f900', '\U0000fa6d'),
- ('\U0000fa70', '\U0000fad9'),
- ('\U00020000', '\U0002a6d6'),
- ('\U0002a700', '\U0002b734'),
- ('\U0002b740', '\U0002b81d'),
- ('\U0002f800', '\U0002fa1d')
- ]),
-("Hangul", &[
- ('\U00001100', '\U000011ff'),
- ('\U0000302e', '\U0000302f'),
- ('\U00003131', '\U0000318e'),
- ('\U00003200', '\U0000321e'),
- ('\U00003260', '\U0000327e'),
- ('\U0000a960', '\U0000a97c'),
- ('\U0000ac00', '\U0000d7a3'),
- ('\U0000d7b0', '\U0000d7c6'),
- ('\U0000d7cb', '\U0000d7fb'),
- ('\U0000ffa0', '\U0000ffbe'),
- ('\U0000ffc2', '\U0000ffc7'),
- ('\U0000ffca', '\U0000ffcf'),
- ('\U0000ffd2', '\U0000ffd7'),
- ('\U0000ffda', '\U0000ffdc')
- ]),
-("Hanunoo", &[
- ('\U00001720', '\U00001734')
- ]),
-("Hebrew", &[
- ('\U00000591', '\U000005c7'),
- ('\U000005d0', '\U000005ea'),
- ('\U000005f0', '\U000005f4'),
- ('\U0000fb1d', '\U0000fb36'),
- ('\U0000fb38', '\U0000fb3c'),
- ('\U0000fb3e', '\U0000fb3e'),
- ('\U0000fb40', '\U0000fb41'),
- ('\U0000fb43', '\U0000fb44'),
- ('\U0000fb46', '\U0000fb4f')
- ]),
-("Hiragana", &[
- ('\U00003041', '\U00003096'),
- ('\U0000309d', '\U0000309f'),
- ('\U0001b001', '\U0001b001'),
- ('\U0001f200', '\U0001f200')
- ]),
-("Imperial_Aramaic", &[
- ('\U00010840', '\U00010855'),
- ('\U00010857', '\U0001085f')
- ]),
-("Inherited", &[
- ('\U00000300', '\U0000036f'),
- ('\U00000485', '\U00000486'),
- ('\U0000064b', '\U00000655'),
- ('\U00000670', '\U00000670'),
- ('\U00000951', '\U00000952'),
- ('\U00001cd0', '\U00001cd2'),
- ('\U00001cd4', '\U00001ce0'),
- ('\U00001ce2', '\U00001ce8'),
- ('\U00001ced', '\U00001ced'),
- ('\U00001cf4', '\U00001cf4'),
- ('\U00001dc0', '\U00001de6'),
- ('\U00001dfc', '\U00001dff'),
- ('\U0000200c', '\U0000200d'),
- ('\U000020d0', '\U000020f0'),
- ('\U0000302a', '\U0000302d'),
- ('\U00003099', '\U0000309a'),
- ('\U0000fe00', '\U0000fe0f'),
- ('\U0000fe20', '\U0000fe26'),
- ('\U000101fd', '\U000101fd'),
- ('\U0001d167', '\U0001d169'),
- ('\U0001d17b', '\U0001d182'),
- ('\U0001d185', '\U0001d18b'),
- ('\U0001d1aa', '\U0001d1ad'),
- ('\U000e0100', '\U000e01ef')
- ]),
-("Inscriptional_Pahlavi", &[
- ('\U00010b60', '\U00010b72'),
- ('\U00010b78', '\U00010b7f')
- ]),
-("Inscriptional_Parthian", &[
- ('\U00010b40', '\U00010b55'),
- ('\U00010b58', '\U00010b5f')
- ]),
-("Javanese", &[
- ('\U0000a980', '\U0000a9cd'),
- ('\U0000a9d0', '\U0000a9d9'),
- ('\U0000a9de', '\U0000a9df')
- ]),
-("Kaithi", &[
- ('\U00011080', '\U000110c1')
- ]),
-("Kannada", &[
- ('\U00000c82', '\U00000c83'),
- ('\U00000c85', '\U00000c8c'),
- ('\U00000c8e', '\U00000c90'),
- ('\U00000c92', '\U00000ca8'),
- ('\U00000caa', '\U00000cb3'),
- ('\U00000cb5', '\U00000cb9'),
- ('\U00000cbc', '\U00000cc4'),
- ('\U00000cc6', '\U00000cc8'),
- ('\U00000cca', '\U00000ccd'),
- ('\U00000cd5', '\U00000cd6'),
- ('\U00000cde', '\U00000cde'),
- ('\U00000ce0', '\U00000ce3'),
- ('\U00000ce6', '\U00000cef'),
- ('\U00000cf1', '\U00000cf2')
- ]),
-("Katakana", &[
- ('\U000030a1', '\U000030fa'),
- ('\U000030fd', '\U000030ff'),
- ('\U000031f0', '\U000031ff'),
- ('\U000032d0', '\U000032fe'),
- ('\U00003300', '\U00003357'),
- ('\U0000ff66', '\U0000ff6f'),
- ('\U0000ff71', '\U0000ff9d'),
- ('\U0001b000', '\U0001b000')
- ]),
-("Kayah_Li", &[
- ('\U0000a900', '\U0000a92f')
- ]),
-("Kharoshthi", &[
- ('\U00010a00', '\U00010a03'),
- ('\U00010a05', '\U00010a06'),
- ('\U00010a0c', '\U00010a13'),
- ('\U00010a15', '\U00010a17'),
- ('\U00010a19', '\U00010a33'),
- ('\U00010a38', '\U00010a3a'),
- ('\U00010a3f', '\U00010a47'),
- ('\U00010a50', '\U00010a58')
- ]),
-("Khmer", &[
- ('\U00001780', '\U000017dd'),
- ('\U000017e0', '\U000017e9'),
- ('\U000017f0', '\U000017f9'),
- ('\U000019e0', '\U000019ff')
- ]),
-("L", &[
- ('\U00000041', '\U0000005a'),
- ('\U00000061', '\U0000007a'),
- ('\U000000aa', '\U000000aa'),
- ('\U000000b5', '\U000000b5'),
- ('\U000000ba', '\U000000ba'),
- ('\U000000c0', '\U000000d6'),
- ('\U000000d8', '\U000000f6'),
- ('\U000000f8', '\U000002c1'),
- ('\U000002c6', '\U000002d1'),
- ('\U000002e0', '\U000002e4'),
- ('\U000002ec', '\U000002ec'),
- ('\U000002ee', '\U000002ee'),
- ('\U00000370', '\U00000374'),
- ('\U00000376', '\U00000377'),
- ('\U0000037a', '\U0000037d'),
- ('\U00000386', '\U00000386'),
- ('\U00000388', '\U0000038a'),
- ('\U0000038c', '\U0000038c'),
- ('\U0000038e', '\U000003a1'),
- ('\U000003a3', '\U000003f5'),
- ('\U000003f7', '\U00000481'),
- ('\U0000048a', '\U00000527'),
- ('\U00000531', '\U00000556'),
- ('\U00000559', '\U00000559'),
- ('\U00000561', '\U00000587'),
- ('\U000005d0', '\U000005ea'),
- ('\U000005f0', '\U000005f2'),
- ('\U00000620', '\U0000064a'),
- ('\U0000066e', '\U0000066f'),
- ('\U00000671', '\U000006d3'),
- ('\U000006d5', '\U000006d5'),
- ('\U000006e5', '\U000006e6'),
- ('\U000006ee', '\U000006ef'),
- ('\U000006fa', '\U000006fc'),
- ('\U000006ff', '\U000006ff'),
- ('\U00000710', '\U00000710'),
- ('\U00000712', '\U0000072f'),
- ('\U0000074d', '\U000007a5'),
- ('\U000007b1', '\U000007b1'),
- ('\U000007ca', '\U000007ea'),
- ('\U000007f4', '\U000007f5'),
- ('\U000007fa', '\U000007fa'),
- ('\U00000800', '\U00000815'),
- ('\U0000081a', '\U0000081a'),
- ('\U00000824', '\U00000824'),
- ('\U00000828', '\U00000828'),
- ('\U00000840', '\U00000858'),
- ('\U000008a0', '\U000008a0'),
- ('\U000008a2', '\U000008ac'),
- ('\U00000904', '\U00000939'),
- ('\U0000093d', '\U0000093d'),
- ('\U00000950', '\U00000950'),
- ('\U00000958', '\U00000961'),
- ('\U00000971', '\U00000977'),
- ('\U00000979', '\U0000097f'),
- ('\U00000985', '\U0000098c'),
- ('\U0000098f', '\U00000990'),
- ('\U00000993', '\U000009a8'),
- ('\U000009aa', '\U000009b0'),
- ('\U000009b2', '\U000009b2'),
- ('\U000009b6', '\U000009b9'),
- ('\U000009bd', '\U000009bd'),
- ('\U000009ce', '\U000009ce'),
- ('\U000009dc', '\U000009dd'),
- ('\U000009df', '\U000009e1'),
- ('\U000009f0', '\U000009f1'),
- ('\U00000a05', '\U00000a0a'),
- ('\U00000a0f', '\U00000a10'),
- ('\U00000a13', '\U00000a28'),
- ('\U00000a2a', '\U00000a30'),
- ('\U00000a32', '\U00000a33'),
- ('\U00000a35', '\U00000a36'),
- ('\U00000a38', '\U00000a39'),
- ('\U00000a59', '\U00000a5c'),
- ('\U00000a5e', '\U00000a5e'),
- ('\U00000a72', '\U00000a74'),
- ('\U00000a85', '\U00000a8d'),
- ('\U00000a8f', '\U00000a91'),
- ('\U00000a93', '\U00000aa8'),
- ('\U00000aaa', '\U00000ab0'),
- ('\U00000ab2', '\U00000ab3'),
- ('\U00000ab5', '\U00000ab9'),
- ('\U00000abd', '\U00000abd'),
- ('\U00000ad0', '\U00000ad0'),
- ('\U00000ae0', '\U00000ae1'),
- ('\U00000b05', '\U00000b0c'),
- ('\U00000b0f', '\U00000b10'),
- ('\U00000b13', '\U00000b28'),
- ('\U00000b2a', '\U00000b30'),
- ('\U00000b32', '\U00000b33'),
- ('\U00000b35', '\U00000b39'),
- ('\U00000b3d', '\U00000b3d'),
- ('\U00000b5c', '\U00000b5d'),
- ('\U00000b5f', '\U00000b61'),
- ('\U00000b71', '\U00000b71'),
- ('\U00000b83', '\U00000b83'),
- ('\U00000b85', '\U00000b8a'),
- ('\U00000b8e', '\U00000b90'),
- ('\U00000b92', '\U00000b95'),
- ('\U00000b99', '\U00000b9a'),
- ('\U00000b9c', '\U00000b9c'),
- ('\U00000b9e', '\U00000b9f'),
- ('\U00000ba3', '\U00000ba4'),
- ('\U00000ba8', '\U00000baa'),
- ('\U00000bae', '\U00000bb9'),
- ('\U00000bd0', '\U00000bd0'),
- ('\U00000c05', '\U00000c0c'),
- ('\U00000c0e', '\U00000c10'),
- ('\U00000c12', '\U00000c28'),
- ('\U00000c2a', '\U00000c33'),
- ('\U00000c35', '\U00000c39'),
- ('\U00000c3d', '\U00000c3d'),
- ('\U00000c58', '\U00000c59'),
- ('\U00000c60', '\U00000c61'),
- ('\U00000c85', '\U00000c8c'),
- ('\U00000c8e', '\U00000c90'),
- ('\U00000c92', '\U00000ca8'),
- ('\U00000caa', '\U00000cb3'),
- ('\U00000cb5', '\U00000cb9'),
- ('\U00000cbd', '\U00000cbd'),
- ('\U00000cde', '\U00000cde'),
- ('\U00000ce0', '\U00000ce1'),
- ('\U00000cf1', '\U00000cf2'),
- ('\U00000d05', '\U00000d0c'),
- ('\U00000d0e', '\U00000d10'),
- ('\U00000d12', '\U00000d3a'),
- ('\U00000d3d', '\U00000d3d'),
- ('\U00000d4e', '\U00000d4e'),
- ('\U00000d60', '\U00000d61'),
- ('\U00000d7a', '\U00000d7f'),
- ('\U00000d85', '\U00000d96'),
- ('\U00000d9a', '\U00000db1'),
- ('\U00000db3', '\U00000dbb'),
- ('\U00000dbd', '\U00000dbd'),
- ('\U00000dc0', '\U00000dc6'),
- ('\U00000e01', '\U00000e30'),
- ('\U00000e32', '\U00000e33'),
- ('\U00000e40', '\U00000e46'),
- ('\U00000e81', '\U00000e82'),
- ('\U00000e84', '\U00000e84'),
- ('\U00000e87', '\U00000e88'),
- ('\U00000e8a', '\U00000e8a'),
- ('\U00000e8d', '\U00000e8d'),
- ('\U00000e94', '\U00000e97'),
- ('\U00000e99', '\U00000e9f'),
- ('\U00000ea1', '\U00000ea3'),
- ('\U00000ea5', '\U00000ea5'),
- ('\U00000ea7', '\U00000ea7'),
- ('\U00000eaa', '\U00000eab'),
- ('\U00000ead', '\U00000eb0'),
- ('\U00000eb2', '\U00000eb3'),
- ('\U00000ebd', '\U00000ebd'),
- ('\U00000ec0', '\U00000ec4'),
- ('\U00000ec6', '\U00000ec6'),
- ('\U00000edc', '\U00000edf'),
- ('\U00000f00', '\U00000f00'),
- ('\U00000f40', '\U00000f47'),
- ('\U00000f49', '\U00000f6c'),
- ('\U00000f88', '\U00000f8c'),
- ('\U00001000', '\U0000102a'),
- ('\U0000103f', '\U0000103f'),
- ('\U00001050', '\U00001055'),
- ('\U0000105a', '\U0000105d'),
- ('\U00001061', '\U00001061'),
- ('\U00001065', '\U00001066'),
- ('\U0000106e', '\U00001070'),
- ('\U00001075', '\U00001081'),
- ('\U0000108e', '\U0000108e'),
- ('\U000010a0', '\U000010c5'),
- ('\U000010c7', '\U000010c7'),
- ('\U000010cd', '\U000010cd'),
- ('\U000010d0', '\U000010fa'),
- ('\U000010fc', '\U00001248'),
- ('\U0000124a', '\U0000124d'),
- ('\U00001250', '\U00001256'),
- ('\U00001258', '\U00001258'),
- ('\U0000125a', '\U0000125d'),
- ('\U00001260', '\U00001288'),
- ('\U0000128a', '\U0000128d'),
- ('\U00001290', '\U000012b0'),
- ('\U000012b2', '\U000012b5'),
- ('\U000012b8', '\U000012be'),
- ('\U000012c0', '\U000012c0'),
- ('\U000012c2', '\U000012c5'),
- ('\U000012c8', '\U000012d6'),
- ('\U000012d8', '\U00001310'),
- ('\U00001312', '\U00001315'),
- ('\U00001318', '\U0000135a'),
- ('\U00001380', '\U0000138f'),
- ('\U000013a0', '\U000013f4'),
- ('\U00001401', '\U0000166c'),
- ('\U0000166f', '\U0000167f'),
- ('\U00001681', '\U0000169a'),
- ('\U000016a0', '\U000016ea'),
- ('\U00001700', '\U0000170c'),
- ('\U0000170e', '\U00001711'),
- ('\U00001720', '\U00001731'),
- ('\U00001740', '\U00001751'),
- ('\U00001760', '\U0000176c'),
- ('\U0000176e', '\U00001770'),
- ('\U00001780', '\U000017b3'),
- ('\U000017d7', '\U000017d7'),
- ('\U000017dc', '\U000017dc'),
- ('\U00001820', '\U00001877'),
- ('\U00001880', '\U000018a8'),
- ('\U000018aa', '\U000018aa'),
- ('\U000018b0', '\U000018f5'),
- ('\U00001900', '\U0000191c'),
- ('\U00001950', '\U0000196d'),
- ('\U00001970', '\U00001974'),
- ('\U00001980', '\U000019ab'),
- ('\U000019c1', '\U000019c7'),
- ('\U00001a00', '\U00001a16'),
- ('\U00001a20', '\U00001a54'),
- ('\U00001aa7', '\U00001aa7'),
- ('\U00001b05', '\U00001b33'),
- ('\U00001b45', '\U00001b4b'),
- ('\U00001b83', '\U00001ba0'),
- ('\U00001bae', '\U00001baf'),
- ('\U00001bba', '\U00001be5'),
- ('\U00001c00', '\U00001c23'),
- ('\U00001c4d', '\U00001c4f'),
- ('\U00001c5a', '\U00001c7d'),
- ('\U00001ce9', '\U00001cec'),
- ('\U00001cee', '\U00001cf1'),
- ('\U00001cf5', '\U00001cf6'),
- ('\U00001d00', '\U00001dbf'),
- ('\U00001e00', '\U00001f15'),
- ('\U00001f18', '\U00001f1d'),
- ('\U00001f20', '\U00001f45'),
- ('\U00001f48', '\U00001f4d'),
- ('\U00001f50', '\U00001f57'),
- ('\U00001f59', '\U00001f59'),
- ('\U00001f5b', '\U00001f5b'),
- ('\U00001f5d', '\U00001f5d'),
- ('\U00001f5f', '\U00001f7d'),
- ('\U00001f80', '\U00001fb4'),
- ('\U00001fb6', '\U00001fbc'),
- ('\U00001fbe', '\U00001fbe'),
- ('\U00001fc2', '\U00001fc4'),
- ('\U00001fc6', '\U00001fcc'),
- ('\U00001fd0', '\U00001fd3'),
- ('\U00001fd6', '\U00001fdb'),
- ('\U00001fe0', '\U00001fec'),
- ('\U00001ff2', '\U00001ff4'),
- ('\U00001ff6', '\U00001ffc'),
- ('\U00002071', '\U00002071'),
- ('\U0000207f', '\U0000207f'),
- ('\U00002090', '\U0000209c'),
- ('\U00002102', '\U00002102'),
- ('\U00002107', '\U00002107'),
- ('\U0000210a', '\U00002113'),
- ('\U00002115', '\U00002115'),
- ('\U00002119', '\U0000211d'),
- ('\U00002124', '\U00002124'),
- ('\U00002126', '\U00002126'),
- ('\U00002128', '\U00002128'),
- ('\U0000212a', '\U0000212d'),
- ('\U0000212f', '\U00002139'),
- ('\U0000213c', '\U0000213f'),
- ('\U00002145', '\U00002149'),
- ('\U0000214e', '\U0000214e'),
- ('\U00002183', '\U00002184'),
- ('\U00002c00', '\U00002c2e'),
- ('\U00002c30', '\U00002c5e'),
- ('\U00002c60', '\U00002ce4'),
- ('\U00002ceb', '\U00002cee'),
- ('\U00002cf2', '\U00002cf3'),
- ('\U00002d00', '\U00002d25'),
- ('\U00002d27', '\U00002d27'),
- ('\U00002d2d', '\U00002d2d'),
- ('\U00002d30', '\U00002d67'),
- ('\U00002d6f', '\U00002d6f'),
- ('\U00002d80', '\U00002d96'),
- ('\U00002da0', '\U00002da6'),
- ('\U00002da8', '\U00002dae'),
- ('\U00002db0', '\U00002db6'),
- ('\U00002db8', '\U00002dbe'),
- ('\U00002dc0', '\U00002dc6'),
- ('\U00002dc8', '\U00002dce'),
- ('\U00002dd0', '\U00002dd6'),
- ('\U00002dd8', '\U00002dde'),
- ('\U00002e2f', '\U00002e2f'),
- ('\U00003005', '\U00003006'),
- ('\U00003031', '\U00003035'),
- ('\U0000303b', '\U0000303c'),
- ('\U00003041', '\U00003096'),
- ('\U0000309d', '\U0000309f'),
- ('\U000030a1', '\U000030fa'),
- ('\U000030fc', '\U000030ff'),
- ('\U00003105', '\U0000312d'),
- ('\U00003131', '\U0000318e'),
- ('\U000031a0', '\U000031ba'),
- ('\U000031f0', '\U000031ff'),
- ('\U00003400', '\U00003400'),
- ('\U00004db5', '\U00004db5'),
- ('\U00004e00', '\U00004e00'),
- ('\U00009fcc', '\U00009fcc'),
- ('\U0000a000', '\U0000a48c'),
- ('\U0000a4d0', '\U0000a4fd'),
- ('\U0000a500', '\U0000a60c'),
- ('\U0000a610', '\U0000a61f'),
- ('\U0000a62a', '\U0000a62b'),
- ('\U0000a640', '\U0000a66e'),
- ('\U0000a67f', '\U0000a697'),
- ('\U0000a6a0', '\U0000a6e5'),
- ('\U0000a717', '\U0000a71f'),
- ('\U0000a722', '\U0000a788'),
- ('\U0000a78b', '\U0000a78e'),
- ('\U0000a790', '\U0000a793'),
- ('\U0000a7a0', '\U0000a7aa'),
- ('\U0000a7f8', '\U0000a801'),
- ('\U0000a803', '\U0000a805'),
- ('\U0000a807', '\U0000a80a'),
- ('\U0000a80c', '\U0000a822'),
- ('\U0000a840', '\U0000a873'),
- ('\U0000a882', '\U0000a8b3'),
- ('\U0000a8f2', '\U0000a8f7'),
- ('\U0000a8fb', '\U0000a8fb'),
- ('\U0000a90a', '\U0000a925'),
- ('\U0000a930', '\U0000a946'),
- ('\U0000a960', '\U0000a97c'),
- ('\U0000a984', '\U0000a9b2'),
- ('\U0000a9cf', '\U0000a9cf'),
- ('\U0000aa00', '\U0000aa28'),
- ('\U0000aa40', '\U0000aa42'),
- ('\U0000aa44', '\U0000aa4b'),
- ('\U0000aa60', '\U0000aa76'),
- ('\U0000aa7a', '\U0000aa7a'),
- ('\U0000aa80', '\U0000aaaf'),
- ('\U0000aab1', '\U0000aab1'),
- ('\U0000aab5', '\U0000aab6'),
- ('\U0000aab9', '\U0000aabd'),
- ('\U0000aac0', '\U0000aac0'),
- ('\U0000aac2', '\U0000aac2'),
- ('\U0000aadb', '\U0000aadd'),
- ('\U0000aae0', '\U0000aaea'),
- ('\U0000aaf2', '\U0000aaf4'),
- ('\U0000ab01', '\U0000ab06'),
- ('\U0000ab09', '\U0000ab0e'),
- ('\U0000ab11', '\U0000ab16'),
- ('\U0000ab20', '\U0000ab26'),
- ('\U0000ab28', '\U0000ab2e'),
- ('\U0000abc0', '\U0000abe2'),
- ('\U0000ac00', '\U0000ac00'),
- ('\U0000d7a3', '\U0000d7a3'),
- ('\U0000d7b0', '\U0000d7c6'),
- ('\U0000d7cb', '\U0000d7fb'),
- ('\U0000f900', '\U0000fa6d'),
- ('\U0000fa70', '\U0000fad9'),
- ('\U0000fb00', '\U0000fb06'),
- ('\U0000fb13', '\U0000fb17'),
- ('\U0000fb1d', '\U0000fb1d'),
- ('\U0000fb1f', '\U0000fb28'),
- ('\U0000fb2a', '\U0000fb36'),
- ('\U0000fb38', '\U0000fb3c'),
- ('\U0000fb3e', '\U0000fb3e'),
- ('\U0000fb40', '\U0000fb41'),
- ('\U0000fb43', '\U0000fb44'),
- ('\U0000fb46', '\U0000fbb1'),
- ('\U0000fbd3', '\U0000fd3d'),
- ('\U0000fd50', '\U0000fd8f'),
- ('\U0000fd92', '\U0000fdc7'),
- ('\U0000fdf0', '\U0000fdfb'),
- ('\U0000fe70', '\U0000fe74'),
- ('\U0000fe76', '\U0000fefc'),
- ('\U0000ff21', '\U0000ff3a'),
- ('\U0000ff41', '\U0000ff5a'),
- ('\U0000ff66', '\U0000ffbe'),
- ('\U0000ffc2', '\U0000ffc7'),
- ('\U0000ffca', '\U0000ffcf'),
- ('\U0000ffd2', '\U0000ffd7'),
- ('\U0000ffda', '\U0000ffdc'),
- ('\U00010000', '\U0001000b'),
- ('\U0001000d', '\U00010026'),
- ('\U00010028', '\U0001003a'),
- ('\U0001003c', '\U0001003d'),
- ('\U0001003f', '\U0001004d'),
- ('\U00010050', '\U0001005d'),
- ('\U00010080', '\U000100fa'),
- ('\U00010280', '\U0001029c'),
- ('\U000102a0', '\U000102d0'),
- ('\U00010300', '\U0001031e'),
- ('\U00010330', '\U00010340'),
- ('\U00010342', '\U00010349'),
- ('\U00010380', '\U0001039d'),
- ('\U000103a0', '\U000103c3'),
- ('\U000103c8', '\U000103cf'),
- ('\U00010400', '\U0001049d'),
- ('\U00010800', '\U00010805'),
- ('\U00010808', '\U00010808'),
- ('\U0001080a', '\U00010835'),
- ('\U00010837', '\U00010838'),
- ('\U0001083c', '\U0001083c'),
- ('\U0001083f', '\U00010855'),
- ('\U00010900', '\U00010915'),
- ('\U00010920', '\U00010939'),
- ('\U00010980', '\U000109b7'),
- ('\U000109be', '\U000109bf'),
- ('\U00010a00', '\U00010a00'),
- ('\U00010a10', '\U00010a13'),
- ('\U00010a15', '\U00010a17'),
- ('\U00010a19', '\U00010a33'),
- ('\U00010a60', '\U00010a7c'),
- ('\U00010b00', '\U00010b35'),
- ('\U00010b40', '\U00010b55'),
- ('\U00010b60', '\U00010b72'),
- ('\U00010c00', '\U00010c48'),
- ('\U00011003', '\U00011037'),
- ('\U00011083', '\U000110af'),
- ('\U000110d0', '\U000110e8'),
- ('\U00011103', '\U00011126'),
- ('\U00011183', '\U000111b2'),
- ('\U000111c1', '\U000111c4'),
- ('\U00011680', '\U000116aa'),
- ('\U00012000', '\U0001236e'),
- ('\U00013000', '\U0001342e'),
- ('\U00016800', '\U00016a38'),
- ('\U00016f00', '\U00016f44'),
- ('\U00016f50', '\U00016f50'),
- ('\U00016f93', '\U00016f9f'),
- ('\U0001b000', '\U0001b001'),
- ('\U0001d400', '\U0001d454'),
- ('\U0001d456', '\U0001d49c'),
- ('\U0001d49e', '\U0001d49f'),
- ('\U0001d4a2', '\U0001d4a2'),
- ('\U0001d4a5', '\U0001d4a6'),
- ('\U0001d4a9', '\U0001d4ac'),
- ('\U0001d4ae', '\U0001d4b9'),
- ('\U0001d4bb', '\U0001d4bb'),
- ('\U0001d4bd', '\U0001d4c3'),
- ('\U0001d4c5', '\U0001d505'),
- ('\U0001d507', '\U0001d50a'),
- ('\U0001d50d', '\U0001d514'),
- ('\U0001d516', '\U0001d51c'),
- ('\U0001d51e', '\U0001d539'),
- ('\U0001d53b', '\U0001d53e'),
- ('\U0001d540', '\U0001d544'),
- ('\U0001d546', '\U0001d546'),
- ('\U0001d54a', '\U0001d550'),
- ('\U0001d552', '\U0001d6a5'),
- ('\U0001d6a8', '\U0001d6c0'),
- ('\U0001d6c2', '\U0001d6da'),
- ('\U0001d6dc', '\U0001d6fa'),
- ('\U0001d6fc', '\U0001d714'),
- ('\U0001d716', '\U0001d734'),
- ('\U0001d736', '\U0001d74e'),
- ('\U0001d750', '\U0001d76e'),
- ('\U0001d770', '\U0001d788'),
- ('\U0001d78a', '\U0001d7a8'),
- ('\U0001d7aa', '\U0001d7c2'),
- ('\U0001d7c4', '\U0001d7cb'),
- ('\U0001ee00', '\U0001ee03'),
- ('\U0001ee05', '\U0001ee1f'),
- ('\U0001ee21', '\U0001ee22'),
- ('\U0001ee24', '\U0001ee24'),
- ('\U0001ee27', '\U0001ee27'),
- ('\U0001ee29', '\U0001ee32'),
- ('\U0001ee34', '\U0001ee37'),
- ('\U0001ee39', '\U0001ee39'),
- ('\U0001ee3b', '\U0001ee3b'),
- ('\U0001ee42', '\U0001ee42'),
- ('\U0001ee47', '\U0001ee47'),
- ('\U0001ee49', '\U0001ee49'),
- ('\U0001ee4b', '\U0001ee4b'),
- ('\U0001ee4d', '\U0001ee4f'),
- ('\U0001ee51', '\U0001ee52'),
- ('\U0001ee54', '\U0001ee54'),
- ('\U0001ee57', '\U0001ee57'),
- ('\U0001ee59', '\U0001ee59'),
- ('\U0001ee5b', '\U0001ee5b'),
- ('\U0001ee5d', '\U0001ee5d'),
- ('\U0001ee5f', '\U0001ee5f'),
- ('\U0001ee61', '\U0001ee62'),
- ('\U0001ee64', '\U0001ee64'),
- ('\U0001ee67', '\U0001ee6a'),
- ('\U0001ee6c', '\U0001ee72'),
- ('\U0001ee74', '\U0001ee77'),
- ('\U0001ee79', '\U0001ee7c'),
- ('\U0001ee7e', '\U0001ee7e'),
- ('\U0001ee80', '\U0001ee89'),
- ('\U0001ee8b', '\U0001ee9b'),
- ('\U0001eea1', '\U0001eea3'),
- ('\U0001eea5', '\U0001eea9'),
- ('\U0001eeab', '\U0001eebb'),
- ('\U00020000', '\U00020000'),
- ('\U0002a6d6', '\U0002a6d6'),
- ('\U0002a700', '\U0002a700'),
- ('\U0002b734', '\U0002b734'),
- ('\U0002b740', '\U0002b740'),
- ('\U0002b81d', '\U0002b81d'),
- ('\U0002f800', '\U0002fa1d')
- ]),
-("LC", &[
- ('\U00000041', '\U0000005a'),
- ('\U00000061', '\U0000007a'),
- ('\U000000b5', '\U000000b5'),
- ('\U000000c0', '\U000000d6'),
- ('\U000000d8', '\U000000f6'),
- ('\U000000f8', '\U000001ba'),
- ('\U000001bc', '\U000001bf'),
- ('\U000001c4', '\U00000293'),
- ('\U00000295', '\U000002af'),
- ('\U00000370', '\U00000373'),
- ('\U00000376', '\U00000377'),
- ('\U0000037b', '\U0000037d'),
- ('\U00000386', '\U00000386'),
- ('\U00000388', '\U0000038a'),
- ('\U0000038c', '\U0000038c'),
- ('\U0000038e', '\U000003a1'),
- ('\U000003a3', '\U000003f5'),
- ('\U000003f7', '\U00000481'),
- ('\U0000048a', '\U00000527'),
- ('\U00000531', '\U00000556'),
- ('\U00000561', '\U00000587'),
- ('\U000010a0', '\U000010c5'),
- ('\U000010c7', '\U000010c7'),
- ('\U000010cd', '\U000010cd'),
- ('\U00001d00', '\U00001d2b'),
- ('\U00001d6b', '\U00001d77'),
- ('\U00001d79', '\U00001d9a'),
- ('\U00001e00', '\U00001f15'),
- ('\U00001f18', '\U00001f1d'),
- ('\U00001f20', '\U00001f45'),
- ('\U00001f48', '\U00001f4d'),
- ('\U00001f50', '\U00001f57'),
- ('\U00001f59', '\U00001f59'),
- ('\U00001f5b', '\U00001f5b'),
- ('\U00001f5d', '\U00001f5d'),
- ('\U00001f5f', '\U00001f7d'),
- ('\U00001f80', '\U00001fb4'),
- ('\U00001fb6', '\U00001fbc'),
- ('\U00001fbe', '\U00001fbe'),
- ('\U00001fc2', '\U00001fc4'),
- ('\U00001fc6', '\U00001fcc'),
- ('\U00001fd0', '\U00001fd3'),
- ('\U00001fd6', '\U00001fdb'),
- ('\U00001fe0', '\U00001fec'),
- ('\U00001ff2', '\U00001ff4'),
- ('\U00001ff6', '\U00001ffc'),
- ('\U00002102', '\U00002102'),
- ('\U00002107', '\U00002107'),
- ('\U0000210a', '\U00002113'),
- ('\U00002115', '\U00002115'),
- ('\U00002119', '\U0000211d'),
- ('\U00002124', '\U00002124'),
- ('\U00002126', '\U00002126'),
- ('\U00002128', '\U00002128'),
- ('\U0000212a', '\U0000212d'),
- ('\U0000212f', '\U00002134'),
- ('\U00002139', '\U00002139'),
- ('\U0000213c', '\U0000213f'),
- ('\U00002145', '\U00002149'),
- ('\U0000214e', '\U0000214e'),
- ('\U00002183', '\U00002184'),
- ('\U00002c00', '\U00002c2e'),
- ('\U00002c30', '\U00002c5e'),
- ('\U00002c60', '\U00002c7b'),
- ('\U00002c7e', '\U00002ce4'),
- ('\U00002ceb', '\U00002cee'),
- ('\U00002cf2', '\U00002cf3'),
- ('\U00002d00', '\U00002d25'),
- ('\U00002d27', '\U00002d27'),
- ('\U00002d2d', '\U00002d2d'),
- ('\U0000a640', '\U0000a66d'),
- ('\U0000a680', '\U0000a697'),
- ('\U0000a722', '\U0000a76f'),
- ('\U0000a771', '\U0000a787'),
- ('\U0000a78b', '\U0000a78e'),
- ('\U0000a790', '\U0000a793'),
- ('\U0000a7a0', '\U0000a7aa'),
- ('\U0000a7fa', '\U0000a7fa'),
- ('\U0000fb00', '\U0000fb06'),
- ('\U0000fb13', '\U0000fb17'),
- ('\U0000ff21', '\U0000ff3a'),
- ('\U0000ff41', '\U0000ff5a'),
- ('\U00010400', '\U0001044f'),
- ('\U0001d400', '\U0001d454'),
- ('\U0001d456', '\U0001d49c'),
- ('\U0001d49e', '\U0001d49f'),
- ('\U0001d4a2', '\U0001d4a2'),
- ('\U0001d4a5', '\U0001d4a6'),
- ('\U0001d4a9', '\U0001d4ac'),
- ('\U0001d4ae', '\U0001d4b9'),
- ('\U0001d4bb', '\U0001d4bb'),
- ('\U0001d4bd', '\U0001d4c3'),
- ('\U0001d4c5', '\U0001d505'),
- ('\U0001d507', '\U0001d50a'),
- ('\U0001d50d', '\U0001d514'),
- ('\U0001d516', '\U0001d51c'),
- ('\U0001d51e', '\U0001d539'),
- ('\U0001d53b', '\U0001d53e'),
- ('\U0001d540', '\U0001d544'),
- ('\U0001d546', '\U0001d546'),
- ('\U0001d54a', '\U0001d550'),
- ('\U0001d552', '\U0001d6a5'),
- ('\U0001d6a8', '\U0001d6c0'),
- ('\U0001d6c2', '\U0001d6da'),
- ('\U0001d6dc', '\U0001d6fa'),
- ('\U0001d6fc', '\U0001d714'),
- ('\U0001d716', '\U0001d734'),
- ('\U0001d736', '\U0001d74e'),
- ('\U0001d750', '\U0001d76e'),
- ('\U0001d770', '\U0001d788'),
- ('\U0001d78a', '\U0001d7a8'),
- ('\U0001d7aa', '\U0001d7c2'),
- ('\U0001d7c4', '\U0001d7cb')
- ]),
-("Lao", &[
- ('\U00000e81', '\U00000e82'),
- ('\U00000e84', '\U00000e84'),
- ('\U00000e87', '\U00000e88'),
- ('\U00000e8a', '\U00000e8a'),
- ('\U00000e8d', '\U00000e8d'),
- ('\U00000e94', '\U00000e97'),
- ('\U00000e99', '\U00000e9f'),
- ('\U00000ea1', '\U00000ea3'),
- ('\U00000ea5', '\U00000ea5'),
- ('\U00000ea7', '\U00000ea7'),
- ('\U00000eaa', '\U00000eab'),
- ('\U00000ead', '\U00000eb9'),
- ('\U00000ebb', '\U00000ebd'),
- ('\U00000ec0', '\U00000ec4'),
- ('\U00000ec6', '\U00000ec6'),
- ('\U00000ec8', '\U00000ecd'),
- ('\U00000ed0', '\U00000ed9'),
- ('\U00000edc', '\U00000edf')
- ]),
-("Latin", &[
- ('\U00000041', '\U0000005a'),
- ('\U00000061', '\U0000007a'),
- ('\U000000aa', '\U000000aa'),
- ('\U000000ba', '\U000000ba'),
- ('\U000000c0', '\U000000d6'),
- ('\U000000d8', '\U000000f6'),
- ('\U000000f8', '\U000002b8'),
- ('\U000002e0', '\U000002e4'),
- ('\U00001d00', '\U00001d25'),
- ('\U00001d2c', '\U00001d5c'),
- ('\U00001d62', '\U00001d65'),
- ('\U00001d6b', '\U00001d77'),
- ('\U00001d79', '\U00001dbe'),
- ('\U00001e00', '\U00001eff'),
- ('\U00002071', '\U00002071'),
- ('\U0000207f', '\U0000207f'),
- ('\U00002090', '\U0000209c'),
- ('\U0000212a', '\U0000212b'),
- ('\U00002132', '\U00002132'),
- ('\U0000214e', '\U0000214e'),
- ('\U00002160', '\U00002188'),
- ('\U00002c60', '\U00002c7f'),
- ('\U0000a722', '\U0000a787'),
- ('\U0000a78b', '\U0000a78e'),
- ('\U0000a790', '\U0000a793'),
- ('\U0000a7a0', '\U0000a7aa'),
- ('\U0000a7f8', '\U0000a7ff'),
- ('\U0000fb00', '\U0000fb06'),
- ('\U0000ff21', '\U0000ff3a'),
- ('\U0000ff41', '\U0000ff5a')
- ]),
-("Lepcha", &[
- ('\U00001c00', '\U00001c37'),
- ('\U00001c3b', '\U00001c49'),
- ('\U00001c4d', '\U00001c4f')
- ]),
-("Limbu", &[
- ('\U00001900', '\U0000191c'),
- ('\U00001920', '\U0000192b'),
- ('\U00001930', '\U0000193b'),
- ('\U00001940', '\U00001940'),
- ('\U00001944', '\U0000194f')
- ]),
-("Linear_B", &[
- ('\U00010000', '\U0001000b'),
- ('\U0001000d', '\U00010026'),
- ('\U00010028', '\U0001003a'),
- ('\U0001003c', '\U0001003d'),
- ('\U0001003f', '\U0001004d'),
- ('\U00010050', '\U0001005d'),
- ('\U00010080', '\U000100fa')
- ]),
-("Lisu", &[
- ('\U0000a4d0', '\U0000a4ff')
- ]),
-("Ll", &[
- ('\U00000061', '\U0000007a'),
- ('\U000000b5', '\U000000b5'),
- ('\U000000df', '\U000000f6'),
- ('\U000000f8', '\U000000ff'),
- ('\U00000101', '\U00000101'),
- ('\U00000103', '\U00000103'),
- ('\U00000105', '\U00000105'),
- ('\U00000107', '\U00000107'),
- ('\U00000109', '\U00000109'),
- ('\U0000010b', '\U0000010b'),
- ('\U0000010d', '\U0000010d'),
- ('\U0000010f', '\U0000010f'),
- ('\U00000111', '\U00000111'),
- ('\U00000113', '\U00000113'),
- ('\U00000115', '\U00000115'),
- ('\U00000117', '\U00000117'),
- ('\U00000119', '\U00000119'),
- ('\U0000011b', '\U0000011b'),
- ('\U0000011d', '\U0000011d'),
- ('\U0000011f', '\U0000011f'),
- ('\U00000121', '\U00000121'),
- ('\U00000123', '\U00000123'),
- ('\U00000125', '\U00000125'),
- ('\U00000127', '\U00000127'),
- ('\U00000129', '\U00000129'),
- ('\U0000012b', '\U0000012b'),
- ('\U0000012d', '\U0000012d'),
- ('\U0000012f', '\U0000012f'),
- ('\U00000131', '\U00000131'),
- ('\U00000133', '\U00000133'),
- ('\U00000135', '\U00000135'),
- ('\U00000137', '\U00000138'),
- ('\U0000013a', '\U0000013a'),
- ('\U0000013c', '\U0000013c'),
- ('\U0000013e', '\U0000013e'),
- ('\U00000140', '\U00000140'),
- ('\U00000142', '\U00000142'),
- ('\U00000144', '\U00000144'),
- ('\U00000146', '\U00000146'),
- ('\U00000148', '\U00000149'),
- ('\U0000014b', '\U0000014b'),
- ('\U0000014d', '\U0000014d'),
- ('\U0000014f', '\U0000014f'),
- ('\U00000151', '\U00000151'),
- ('\U00000153', '\U00000153'),
- ('\U00000155', '\U00000155'),
- ('\U00000157', '\U00000157'),
- ('\U00000159', '\U00000159'),
- ('\U0000015b', '\U0000015b'),
- ('\U0000015d', '\U0000015d'),
- ('\U0000015f', '\U0000015f'),
- ('\U00000161', '\U00000161'),
- ('\U00000163', '\U00000163'),
- ('\U00000165', '\U00000165'),
- ('\U00000167', '\U00000167'),
- ('\U00000169', '\U00000169'),
- ('\U0000016b', '\U0000016b'),
- ('\U0000016d', '\U0000016d'),
- ('\U0000016f', '\U0000016f'),
- ('\U00000171', '\U00000171'),
- ('\U00000173', '\U00000173'),
- ('\U00000175', '\U00000175'),
- ('\U00000177', '\U00000177'),
- ('\U0000017a', '\U0000017a'),
- ('\U0000017c', '\U0000017c'),
- ('\U0000017e', '\U00000180'),
- ('\U00000183', '\U00000183'),
- ('\U00000185', '\U00000185'),
- ('\U00000188', '\U00000188'),
- ('\U0000018c', '\U0000018d'),
- ('\U00000192', '\U00000192'),
- ('\U00000195', '\U00000195'),
- ('\U00000199', '\U0000019b'),
- ('\U0000019e', '\U0000019e'),
- ('\U000001a1', '\U000001a1'),
- ('\U000001a3', '\U000001a3'),
- ('\U000001a5', '\U000001a5'),
- ('\U000001a8', '\U000001a8'),
- ('\U000001aa', '\U000001ab'),
- ('\U000001ad', '\U000001ad'),
- ('\U000001b0', '\U000001b0'),
- ('\U000001b4', '\U000001b4'),
- ('\U000001b6', '\U000001b6'),
- ('\U000001b9', '\U000001ba'),
- ('\U000001bd', '\U000001bf'),
- ('\U000001c6', '\U000001c6'),
- ('\U000001c9', '\U000001c9'),
- ('\U000001cc', '\U000001cc'),
- ('\U000001ce', '\U000001ce'),
- ('\U000001d0', '\U000001d0'),
- ('\U000001d2', '\U000001d2'),
- ('\U000001d4', '\U000001d4'),
- ('\U000001d6', '\U000001d6'),
- ('\U000001d8', '\U000001d8'),
- ('\U000001da', '\U000001da'),
- ('\U000001dc', '\U000001dd'),
- ('\U000001df', '\U000001df'),
- ('\U000001e1', '\U000001e1'),
- ('\U000001e3', '\U000001e3'),
- ('\U000001e5', '\U000001e5'),
- ('\U000001e7', '\U000001e7'),
- ('\U000001e9', '\U000001e9'),
- ('\U000001eb', '\U000001eb'),
- ('\U000001ed', '\U000001ed'),
- ('\U000001ef', '\U000001f0'),
- ('\U000001f3', '\U000001f3'),
- ('\U000001f5', '\U000001f5'),
- ('\U000001f9', '\U000001f9'),
- ('\U000001fb', '\U000001fb'),
- ('\U000001fd', '\U000001fd'),
- ('\U000001ff', '\U000001ff'),
- ('\U00000201', '\U00000201'),
- ('\U00000203', '\U00000203'),
- ('\U00000205', '\U00000205'),
- ('\U00000207', '\U00000207'),
- ('\U00000209', '\U00000209'),
- ('\U0000020b', '\U0000020b'),
- ('\U0000020d', '\U0000020d'),
- ('\U0000020f', '\U0000020f'),
- ('\U00000211', '\U00000211'),
- ('\U00000213', '\U00000213'),
- ('\U00000215', '\U00000215'),
- ('\U00000217', '\U00000217'),
- ('\U00000219', '\U00000219'),
- ('\U0000021b', '\U0000021b'),
- ('\U0000021d', '\U0000021d'),
- ('\U0000021f', '\U0000021f'),
- ('\U00000221', '\U00000221'),
- ('\U00000223', '\U00000223'),
- ('\U00000225', '\U00000225'),
- ('\U00000227', '\U00000227'),
- ('\U00000229', '\U00000229'),
- ('\U0000022b', '\U0000022b'),
- ('\U0000022d', '\U0000022d'),
- ('\U0000022f', '\U0000022f'),
- ('\U00000231', '\U00000231'),
- ('\U00000233', '\U00000239'),
- ('\U0000023c', '\U0000023c'),
- ('\U0000023f', '\U00000240'),
- ('\U00000242', '\U00000242'),
- ('\U00000247', '\U00000247'),
- ('\U00000249', '\U00000249'),
- ('\U0000024b', '\U0000024b'),
- ('\U0000024d', '\U0000024d'),
- ('\U0000024f', '\U00000293'),
- ('\U00000295', '\U000002af'),
- ('\U00000371', '\U00000371'),
- ('\U00000373', '\U00000373'),
- ('\U00000377', '\U00000377'),
- ('\U0000037b', '\U0000037d'),
- ('\U00000390', '\U00000390'),
- ('\U000003ac', '\U000003ce'),
- ('\U000003d0', '\U000003d1'),
- ('\U000003d5', '\U000003d7'),
- ('\U000003d9', '\U000003d9'),
- ('\U000003db', '\U000003db'),
- ('\U000003dd', '\U000003dd'),
- ('\U000003df', '\U000003df'),
- ('\U000003e1', '\U000003e1'),
- ('\U000003e3', '\U000003e3'),
- ('\U000003e5', '\U000003e5'),
- ('\U000003e7', '\U000003e7'),
- ('\U000003e9', '\U000003e9'),
- ('\U000003eb', '\U000003eb'),
- ('\U000003ed', '\U000003ed'),
- ('\U000003ef', '\U000003f3'),
- ('\U000003f5', '\U000003f5'),
- ('\U000003f8', '\U000003f8'),
- ('\U000003fb', '\U000003fc'),
- ('\U00000430', '\U0000045f'),
- ('\U00000461', '\U00000461'),
- ('\U00000463', '\U00000463'),
- ('\U00000465', '\U00000465'),
- ('\U00000467', '\U00000467'),
- ('\U00000469', '\U00000469'),
- ('\U0000046b', '\U0000046b'),
- ('\U0000046d', '\U0000046d'),
- ('\U0000046f', '\U0000046f'),
- ('\U00000471', '\U00000471'),
- ('\U00000473', '\U00000473'),
- ('\U00000475', '\U00000475'),
- ('\U00000477', '\U00000477'),
- ('\U00000479', '\U00000479'),
- ('\U0000047b', '\U0000047b'),
- ('\U0000047d', '\U0000047d'),
- ('\U0000047f', '\U0000047f'),
- ('\U00000481', '\U00000481'),
- ('\U0000048b', '\U0000048b'),
- ('\U0000048d', '\U0000048d'),
- ('\U0000048f', '\U0000048f'),
- ('\U00000491', '\U00000491'),
- ('\U00000493', '\U00000493'),
- ('\U00000495', '\U00000495'),
- ('\U00000497', '\U00000497'),
- ('\U00000499', '\U00000499'),
- ('\U0000049b', '\U0000049b'),
- ('\U0000049d', '\U0000049d'),
- ('\U0000049f', '\U0000049f'),
- ('\U000004a1', '\U000004a1'),
- ('\U000004a3', '\U000004a3'),
- ('\U000004a5', '\U000004a5'),
- ('\U000004a7', '\U000004a7'),
- ('\U000004a9', '\U000004a9'),
- ('\U000004ab', '\U000004ab'),
- ('\U000004ad', '\U000004ad'),
- ('\U000004af', '\U000004af'),
- ('\U000004b1', '\U000004b1'),
- ('\U000004b3', '\U000004b3'),
- ('\U000004b5', '\U000004b5'),
- ('\U000004b7', '\U000004b7'),
- ('\U000004b9', '\U000004b9'),
- ('\U000004bb', '\U000004bb'),
- ('\U000004bd', '\U000004bd'),
- ('\U000004bf', '\U000004bf'),
- ('\U000004c2', '\U000004c2'),
- ('\U000004c4', '\U000004c4'),
- ('\U000004c6', '\U000004c6'),
- ('\U000004c8', '\U000004c8'),
- ('\U000004ca', '\U000004ca'),
- ('\U000004cc', '\U000004cc'),
- ('\U000004ce', '\U000004cf'),
- ('\U000004d1', '\U000004d1'),
- ('\U000004d3', '\U000004d3'),
- ('\U000004d5', '\U000004d5'),
- ('\U000004d7', '\U000004d7'),
- ('\U000004d9', '\U000004d9'),
- ('\U000004db', '\U000004db'),
- ('\U000004dd', '\U000004dd'),
- ('\U000004df', '\U000004df'),
- ('\U000004e1', '\U000004e1'),
- ('\U000004e3', '\U000004e3'),
- ('\U000004e5', '\U000004e5'),
- ('\U000004e7', '\U000004e7'),
- ('\U000004e9', '\U000004e9'),
- ('\U000004eb', '\U000004eb'),
- ('\U000004ed', '\U000004ed'),
- ('\U000004ef', '\U000004ef'),
- ('\U000004f1', '\U000004f1'),
- ('\U000004f3', '\U000004f3'),
- ('\U000004f5', '\U000004f5'),
- ('\U000004f7', '\U000004f7'),
- ('\U000004f9', '\U000004f9'),
- ('\U000004fb', '\U000004fb'),
- ('\U000004fd', '\U000004fd'),
- ('\U000004ff', '\U000004ff'),
- ('\U00000501', '\U00000501'),
- ('\U00000503', '\U00000503'),
- ('\U00000505', '\U00000505'),
- ('\U00000507', '\U00000507'),
- ('\U00000509', '\U00000509'),
- ('\U0000050b', '\U0000050b'),
- ('\U0000050d', '\U0000050d'),
- ('\U0000050f', '\U0000050f'),
- ('\U00000511', '\U00000511'),
- ('\U00000513', '\U00000513'),
- ('\U00000515', '\U00000515'),
- ('\U00000517', '\U00000517'),
- ('\U00000519', '\U00000519'),
- ('\U0000051b', '\U0000051b'),
- ('\U0000051d', '\U0000051d'),
- ('\U0000051f', '\U0000051f'),
- ('\U00000521', '\U00000521'),
- ('\U00000523', '\U00000523'),
- ('\U00000525', '\U00000525'),
- ('\U00000527', '\U00000527'),
- ('\U00000561', '\U00000587'),
- ('\U00001d00', '\U00001d2b'),
- ('\U00001d6b', '\U00001d77'),
- ('\U00001d79', '\U00001d9a'),
- ('\U00001e01', '\U00001e01'),
- ('\U00001e03', '\U00001e03'),
- ('\U00001e05', '\U00001e05'),
- ('\U00001e07', '\U00001e07'),
- ('\U00001e09', '\U00001e09'),
- ('\U00001e0b', '\U00001e0b'),
- ('\U00001e0d', '\U00001e0d'),
- ('\U00001e0f', '\U00001e0f'),
- ('\U00001e11', '\U00001e11'),
- ('\U00001e13', '\U00001e13'),
- ('\U00001e15', '\U00001e15'),
- ('\U00001e17', '\U00001e17'),
- ('\U00001e19', '\U00001e19'),
- ('\U00001e1b', '\U00001e1b'),
- ('\U00001e1d', '\U00001e1d'),
- ('\U00001e1f', '\U00001e1f'),
- ('\U00001e21', '\U00001e21'),
- ('\U00001e23', '\U00001e23'),
- ('\U00001e25', '\U00001e25'),
- ('\U00001e27', '\U00001e27'),
- ('\U00001e29', '\U00001e29'),
- ('\U00001e2b', '\U00001e2b'),
- ('\U00001e2d', '\U00001e2d'),
- ('\U00001e2f', '\U00001e2f'),
- ('\U00001e31', '\U00001e31'),
- ('\U00001e33', '\U00001e33'),
- ('\U00001e35', '\U00001e35'),
- ('\U00001e37', '\U00001e37'),
- ('\U00001e39', '\U00001e39'),
- ('\U00001e3b', '\U00001e3b'),
- ('\U00001e3d', '\U00001e3d'),
- ('\U00001e3f', '\U00001e3f'),
- ('\U00001e41', '\U00001e41'),
- ('\U00001e43', '\U00001e43'),
- ('\U00001e45', '\U00001e45'),
- ('\U00001e47', '\U00001e47'),
- ('\U00001e49', '\U00001e49'),
- ('\U00001e4b', '\U00001e4b'),
- ('\U00001e4d', '\U00001e4d'),
- ('\U00001e4f', '\U00001e4f'),
- ('\U00001e51', '\U00001e51'),
- ('\U00001e53', '\U00001e53'),
- ('\U00001e55', '\U00001e55'),
- ('\U00001e57', '\U00001e57'),
- ('\U00001e59', '\U00001e59'),
- ('\U00001e5b', '\U00001e5b'),
- ('\U00001e5d', '\U00001e5d'),
- ('\U00001e5f', '\U00001e5f'),
- ('\U00001e61', '\U00001e61'),
- ('\U00001e63', '\U00001e63'),
- ('\U00001e65', '\U00001e65'),
- ('\U00001e67', '\U00001e67'),
- ('\U00001e69', '\U00001e69'),
- ('\U00001e6b', '\U00001e6b'),
- ('\U00001e6d', '\U00001e6d'),
- ('\U00001e6f', '\U00001e6f'),
- ('\U00001e71', '\U00001e71'),
- ('\U00001e73', '\U00001e73'),
- ('\U00001e75', '\U00001e75'),
- ('\U00001e77', '\U00001e77'),
- ('\U00001e79', '\U00001e79'),
- ('\U00001e7b', '\U00001e7b'),
- ('\U00001e7d', '\U00001e7d'),
- ('\U00001e7f', '\U00001e7f'),
- ('\U00001e81', '\U00001e81'),
- ('\U00001e83', '\U00001e83'),
- ('\U00001e85', '\U00001e85'),
- ('\U00001e87', '\U00001e87'),
- ('\U00001e89', '\U00001e89'),
- ('\U00001e8b', '\U00001e8b'),
- ('\U00001e8d', '\U00001e8d'),
- ('\U00001e8f', '\U00001e8f'),
- ('\U00001e91', '\U00001e91'),
- ('\U00001e93', '\U00001e93'),
- ('\U00001e95', '\U00001e9d'),
- ('\U00001e9f', '\U00001e9f'),
- ('\U00001ea1', '\U00001ea1'),
- ('\U00001ea3', '\U00001ea3'),
- ('\U00001ea5', '\U00001ea5'),
- ('\U00001ea7', '\U00001ea7'),
- ('\U00001ea9', '\U00001ea9'),
- ('\U00001eab', '\U00001eab'),
- ('\U00001ead', '\U00001ead'),
- ('\U00001eaf', '\U00001eaf'),
- ('\U00001eb1', '\U00001eb1'),
- ('\U00001eb3', '\U00001eb3'),
- ('\U00001eb5', '\U00001eb5'),
- ('\U00001eb7', '\U00001eb7'),
- ('\U00001eb9', '\U00001eb9'),
- ('\U00001ebb', '\U00001ebb'),
- ('\U00001ebd', '\U00001ebd'),
- ('\U00001ebf', '\U00001ebf'),
- ('\U00001ec1', '\U00001ec1'),
- ('\U00001ec3', '\U00001ec3'),
- ('\U00001ec5', '\U00001ec5'),
- ('\U00001ec7', '\U00001ec7'),
- ('\U00001ec9', '\U00001ec9'),
- ('\U00001ecb', '\U00001ecb'),
- ('\U00001ecd', '\U00001ecd'),
- ('\U00001ecf', '\U00001ecf'),
- ('\U00001ed1', '\U00001ed1'),
- ('\U00001ed3', '\U00001ed3'),
- ('\U00001ed5', '\U00001ed5'),
- ('\U00001ed7', '\U00001ed7'),
- ('\U00001ed9', '\U00001ed9'),
- ('\U00001edb', '\U00001edb'),
- ('\U00001edd', '\U00001edd'),
- ('\U00001edf', '\U00001edf'),
- ('\U00001ee1', '\U00001ee1'),
- ('\U00001ee3', '\U00001ee3'),
- ('\U00001ee5', '\U00001ee5'),
- ('\U00001ee7', '\U00001ee7'),
- ('\U00001ee9', '\U00001ee9'),
- ('\U00001eeb', '\U00001eeb'),
- ('\U00001eed', '\U00001eed'),
- ('\U00001eef', '\U00001eef'),
- ('\U00001ef1', '\U00001ef1'),
- ('\U00001ef3', '\U00001ef3'),
- ('\U00001ef5', '\U00001ef5'),
- ('\U00001ef7', '\U00001ef7'),
- ('\U00001ef9', '\U00001ef9'),
- ('\U00001efb', '\U00001efb'),
- ('\U00001efd', '\U00001efd'),
- ('\U00001eff', '\U00001f07'),
- ('\U00001f10', '\U00001f15'),
- ('\U00001f20', '\U00001f27'),
- ('\U00001f30', '\U00001f37'),
- ('\U00001f40', '\U00001f45'),
- ('\U00001f50', '\U00001f57'),
- ('\U00001f60', '\U00001f67'),
- ('\U00001f70', '\U00001f7d'),
- ('\U00001f80', '\U00001f87'),
- ('\U00001f90', '\U00001f97'),
- ('\U00001fa0', '\U00001fa7'),
- ('\U00001fb0', '\U00001fb4'),
- ('\U00001fb6', '\U00001fb7'),
- ('\U00001fbe', '\U00001fbe'),
- ('\U00001fc2', '\U00001fc4'),
- ('\U00001fc6', '\U00001fc7'),
- ('\U00001fd0', '\U00001fd3'),
- ('\U00001fd6', '\U00001fd7'),
- ('\U00001fe0', '\U00001fe7'),
- ('\U00001ff2', '\U00001ff4'),
- ('\U00001ff6', '\U00001ff7'),
- ('\U0000210a', '\U0000210a'),
- ('\U0000210e', '\U0000210f'),
- ('\U00002113', '\U00002113'),
- ('\U0000212f', '\U0000212f'),
- ('\U00002134', '\U00002134'),
- ('\U00002139', '\U00002139'),
- ('\U0000213c', '\U0000213d'),
- ('\U00002146', '\U00002149'),
- ('\U0000214e', '\U0000214e'),
- ('\U00002184', '\U00002184'),
- ('\U00002c30', '\U00002c5e'),
- ('\U00002c61', '\U00002c61'),
- ('\U00002c65', '\U00002c66'),
- ('\U00002c68', '\U00002c68'),
- ('\U00002c6a', '\U00002c6a'),
- ('\U00002c6c', '\U00002c6c'),
- ('\U00002c71', '\U00002c71'),
- ('\U00002c73', '\U00002c74'),
- ('\U00002c76', '\U00002c7b'),
- ('\U00002c81', '\U00002c81'),
- ('\U00002c83', '\U00002c83'),
- ('\U00002c85', '\U00002c85'),
- ('\U00002c87', '\U00002c87'),
- ('\U00002c89', '\U00002c89'),
- ('\U00002c8b', '\U00002c8b'),
- ('\U00002c8d', '\U00002c8d'),
- ('\U00002c8f', '\U00002c8f'),
- ('\U00002c91', '\U00002c91'),
- ('\U00002c93', '\U00002c93'),
- ('\U00002c95', '\U00002c95'),
- ('\U00002c97', '\U00002c97'),
- ('\U00002c99', '\U00002c99'),
- ('\U00002c9b', '\U00002c9b'),
- ('\U00002c9d', '\U00002c9d'),
- ('\U00002c9f', '\U00002c9f'),
- ('\U00002ca1', '\U00002ca1'),
- ('\U00002ca3', '\U00002ca3'),
- ('\U00002ca5', '\U00002ca5'),
- ('\U00002ca7', '\U00002ca7'),
- ('\U00002ca9', '\U00002ca9'),
- ('\U00002cab', '\U00002cab'),
- ('\U00002cad', '\U00002cad'),
- ('\U00002caf', '\U00002caf'),
- ('\U00002cb1', '\U00002cb1'),
- ('\U00002cb3', '\U00002cb3'),
- ('\U00002cb5', '\U00002cb5'),
- ('\U00002cb7', '\U00002cb7'),
- ('\U00002cb9', '\U00002cb9'),
- ('\U00002cbb', '\U00002cbb'),
- ('\U00002cbd', '\U00002cbd'),
- ('\U00002cbf', '\U00002cbf'),
- ('\U00002cc1', '\U00002cc1'),
- ('\U00002cc3', '\U00002cc3'),
- ('\U00002cc5', '\U00002cc5'),
- ('\U00002cc7', '\U00002cc7'),
- ('\U00002cc9', '\U00002cc9'),
- ('\U00002ccb', '\U00002ccb'),
- ('\U00002ccd', '\U00002ccd'),
- ('\U00002ccf', '\U00002ccf'),
- ('\U00002cd1', '\U00002cd1'),
- ('\U00002cd3', '\U00002cd3'),
- ('\U00002cd5', '\U00002cd5'),
- ('\U00002cd7', '\U00002cd7'),
- ('\U00002cd9', '\U00002cd9'),
- ('\U00002cdb', '\U00002cdb'),
- ('\U00002cdd', '\U00002cdd'),
- ('\U00002cdf', '\U00002cdf'),
- ('\U00002ce1', '\U00002ce1'),
- ('\U00002ce3', '\U00002ce4'),
- ('\U00002cec', '\U00002cec'),
- ('\U00002cee', '\U00002cee'),
- ('\U00002cf3', '\U00002cf3'),
- ('\U00002d00', '\U00002d25'),
- ('\U00002d27', '\U00002d27'),
- ('\U00002d2d', '\U00002d2d'),
- ('\U0000a641', '\U0000a641'),
- ('\U0000a643', '\U0000a643'),
- ('\U0000a645', '\U0000a645'),
- ('\U0000a647', '\U0000a647'),
- ('\U0000a649', '\U0000a649'),
- ('\U0000a64b', '\U0000a64b'),
- ('\U0000a64d', '\U0000a64d'),
- ('\U0000a64f', '\U0000a64f'),
- ('\U0000a651', '\U0000a651'),
- ('\U0000a653', '\U0000a653'),
- ('\U0000a655', '\U0000a655'),
- ('\U0000a657', '\U0000a657'),
- ('\U0000a659', '\U0000a659'),
- ('\U0000a65b', '\U0000a65b'),
- ('\U0000a65d', '\U0000a65d'),
- ('\U0000a65f', '\U0000a65f'),
- ('\U0000a661', '\U0000a661'),
- ('\U0000a663', '\U0000a663'),
- ('\U0000a665', '\U0000a665'),
- ('\U0000a667', '\U0000a667'),
- ('\U0000a669', '\U0000a669'),
- ('\U0000a66b', '\U0000a66b'),
- ('\U0000a66d', '\U0000a66d'),
- ('\U0000a681', '\U0000a681'),
- ('\U0000a683', '\U0000a683'),
- ('\U0000a685', '\U0000a685'),
- ('\U0000a687', '\U0000a687'),
- ('\U0000a689', '\U0000a689'),
- ('\U0000a68b', '\U0000a68b'),
- ('\U0000a68d', '\U0000a68d'),
- ('\U0000a68f', '\U0000a68f'),
- ('\U0000a691', '\U0000a691'),
- ('\U0000a693', '\U0000a693'),
- ('\U0000a695', '\U0000a695'),
- ('\U0000a697', '\U0000a697'),
- ('\U0000a723', '\U0000a723'),
- ('\U0000a725', '\U0000a725'),
- ('\U0000a727', '\U0000a727'),
- ('\U0000a729', '\U0000a729'),
- ('\U0000a72b', '\U0000a72b'),
- ('\U0000a72d', '\U0000a72d'),
- ('\U0000a72f', '\U0000a731'),
- ('\U0000a733', '\U0000a733'),
- ('\U0000a735', '\U0000a735'),
- ('\U0000a737', '\U0000a737'),
- ('\U0000a739', '\U0000a739'),
- ('\U0000a73b', '\U0000a73b'),
- ('\U0000a73d', '\U0000a73d'),
- ('\U0000a73f', '\U0000a73f'),
- ('\U0000a741', '\U0000a741'),
- ('\U0000a743', '\U0000a743'),
- ('\U0000a745', '\U0000a745'),
- ('\U0000a747', '\U0000a747'),
- ('\U0000a749', '\U0000a749'),
- ('\U0000a74b', '\U0000a74b'),
- ('\U0000a74d', '\U0000a74d'),
- ('\U0000a74f', '\U0000a74f'),
- ('\U0000a751', '\U0000a751'),
- ('\U0000a753', '\U0000a753'),
- ('\U0000a755', '\U0000a755'),
- ('\U0000a757', '\U0000a757'),
- ('\U0000a759', '\U0000a759'),
- ('\U0000a75b', '\U0000a75b'),
- ('\U0000a75d', '\U0000a75d'),
- ('\U0000a75f', '\U0000a75f'),
- ('\U0000a761', '\U0000a761'),
- ('\U0000a763', '\U0000a763'),
- ('\U0000a765', '\U0000a765'),
- ('\U0000a767', '\U0000a767'),
- ('\U0000a769', '\U0000a769'),
- ('\U0000a76b', '\U0000a76b'),
- ('\U0000a76d', '\U0000a76d'),
- ('\U0000a76f', '\U0000a76f'),
- ('\U0000a771', '\U0000a778'),
- ('\U0000a77a', '\U0000a77a'),
- ('\U0000a77c', '\U0000a77c'),
- ('\U0000a77f', '\U0000a77f'),
- ('\U0000a781', '\U0000a781'),
- ('\U0000a783', '\U0000a783'),
- ('\U0000a785', '\U0000a785'),
- ('\U0000a787', '\U0000a787'),
- ('\U0000a78c', '\U0000a78c'),
- ('\U0000a78e', '\U0000a78e'),
- ('\U0000a791', '\U0000a791'),
- ('\U0000a793', '\U0000a793'),
- ('\U0000a7a1', '\U0000a7a1'),
- ('\U0000a7a3', '\U0000a7a3'),
- ('\U0000a7a5', '\U0000a7a5'),
- ('\U0000a7a7', '\U0000a7a7'),
- ('\U0000a7a9', '\U0000a7a9'),
- ('\U0000a7fa', '\U0000a7fa'),
- ('\U0000fb00', '\U0000fb06'),
- ('\U0000fb13', '\U0000fb17'),
- ('\U0000ff41', '\U0000ff5a'),
- ('\U00010428', '\U0001044f'),
- ('\U0001d41a', '\U0001d433'),
- ('\U0001d44e', '\U0001d454'),
- ('\U0001d456', '\U0001d467'),
- ('\U0001d482', '\U0001d49b'),
- ('\U0001d4b6', '\U0001d4b9'),
- ('\U0001d4bb', '\U0001d4bb'),
- ('\U0001d4bd', '\U0001d4c3'),
- ('\U0001d4c5', '\U0001d4cf'),
- ('\U0001d4ea', '\U0001d503'),
- ('\U0001d51e', '\U0001d537'),
- ('\U0001d552', '\U0001d56b'),
- ('\U0001d586', '\U0001d59f'),
- ('\U0001d5ba', '\U0001d5d3'),
- ('\U0001d5ee', '\U0001d607'),
- ('\U0001d622', '\U0001d63b'),
- ('\U0001d656', '\U0001d66f'),
- ('\U0001d68a', '\U0001d6a5'),
- ('\U0001d6c2', '\U0001d6da'),
- ('\U0001d6dc', '\U0001d6e1'),
- ('\U0001d6fc', '\U0001d714'),
- ('\U0001d716', '\U0001d71b'),
- ('\U0001d736', '\U0001d74e'),
- ('\U0001d750', '\U0001d755'),
- ('\U0001d770', '\U0001d788'),
- ('\U0001d78a', '\U0001d78f'),
- ('\U0001d7aa', '\U0001d7c2'),
- ('\U0001d7c4', '\U0001d7c9'),
- ('\U0001d7cb', '\U0001d7cb')
- ]),
-("Lm", &[
- ('\U000002b0', '\U000002c1'),
- ('\U000002c6', '\U000002d1'),
- ('\U000002e0', '\U000002e4'),
- ('\U000002ec', '\U000002ec'),
- ('\U000002ee', '\U000002ee'),
- ('\U00000374', '\U00000374'),
- ('\U0000037a', '\U0000037a'),
- ('\U00000559', '\U00000559'),
- ('\U00000640', '\U00000640'),
- ('\U000006e5', '\U000006e6'),
- ('\U000007f4', '\U000007f5'),
- ('\U000007fa', '\U000007fa'),
- ('\U0000081a', '\U0000081a'),
- ('\U00000824', '\U00000824'),
- ('\U00000828', '\U00000828'),
- ('\U00000971', '\U00000971'),
- ('\U00000e46', '\U00000e46'),
- ('\U00000ec6', '\U00000ec6'),
- ('\U000010fc', '\U000010fc'),
- ('\U000017d7', '\U000017d7'),
- ('\U00001843', '\U00001843'),
- ('\U00001aa7', '\U00001aa7'),
- ('\U00001c78', '\U00001c7d'),
- ('\U00001d2c', '\U00001d6a'),
- ('\U00001d78', '\U00001d78'),
- ('\U00001d9b', '\U00001dbf'),
- ('\U00002071', '\U00002071'),
- ('\U0000207f', '\U0000207f'),
- ('\U00002090', '\U0000209c'),
- ('\U00002c7c', '\U00002c7d'),
- ('\U00002d6f', '\U00002d6f'),
- ('\U00002e2f', '\U00002e2f'),
- ('\U00003005', '\U00003005'),
- ('\U00003031', '\U00003035'),
- ('\U0000303b', '\U0000303b'),
- ('\U0000309d', '\U0000309e'),
- ('\U000030fc', '\U000030fe'),
- ('\U0000a015', '\U0000a015'),
- ('\U0000a4f8', '\U0000a4fd'),
- ('\U0000a60c', '\U0000a60c'),
- ('\U0000a67f', '\U0000a67f'),
- ('\U0000a717', '\U0000a71f'),
- ('\U0000a770', '\U0000a770'),
- ('\U0000a788', '\U0000a788'),
- ('\U0000a7f8', '\U0000a7f9'),
- ('\U0000a9cf', '\U0000a9cf'),
- ('\U0000aa70', '\U0000aa70'),
- ('\U0000aadd', '\U0000aadd'),
- ('\U0000aaf3', '\U0000aaf4'),
- ('\U0000ff70', '\U0000ff70'),
- ('\U0000ff9e', '\U0000ff9f'),
- ('\U00016f93', '\U00016f9f')
- ]),
-("Lo", &[
- ('\U000000aa', '\U000000aa'),
- ('\U000000ba', '\U000000ba'),
- ('\U000001bb', '\U000001bb'),
- ('\U000001c0', '\U000001c3'),
- ('\U00000294', '\U00000294'),
- ('\U000005d0', '\U000005ea'),
- ('\U000005f0', '\U000005f2'),
- ('\U00000620', '\U0000063f'),
- ('\U00000641', '\U0000064a'),
- ('\U0000066e', '\U0000066f'),
- ('\U00000671', '\U000006d3'),
- ('\U000006d5', '\U000006d5'),
- ('\U000006ee', '\U000006ef'),
- ('\U000006fa', '\U000006fc'),
- ('\U000006ff', '\U000006ff'),
- ('\U00000710', '\U00000710'),
- ('\U00000712', '\U0000072f'),
- ('\U0000074d', '\U000007a5'),
- ('\U000007b1', '\U000007b1'),
- ('\U000007ca', '\U000007ea'),
- ('\U00000800', '\U00000815'),
- ('\U00000840', '\U00000858'),
- ('\U000008a0', '\U000008a0'),
- ('\U000008a2', '\U000008ac'),
- ('\U00000904', '\U00000939'),
- ('\U0000093d', '\U0000093d'),
- ('\U00000950', '\U00000950'),
- ('\U00000958', '\U00000961'),
- ('\U00000972', '\U00000977'),
- ('\U00000979', '\U0000097f'),
- ('\U00000985', '\U0000098c'),
- ('\U0000098f', '\U00000990'),
- ('\U00000993', '\U000009a8'),
- ('\U000009aa', '\U000009b0'),
- ('\U000009b2', '\U000009b2'),
- ('\U000009b6', '\U000009b9'),
- ('\U000009bd', '\U000009bd'),
- ('\U000009ce', '\U000009ce'),
- ('\U000009dc', '\U000009dd'),
- ('\U000009df', '\U000009e1'),
- ('\U000009f0', '\U000009f1'),
- ('\U00000a05', '\U00000a0a'),
- ('\U00000a0f', '\U00000a10'),
- ('\U00000a13', '\U00000a28'),
- ('\U00000a2a', '\U00000a30'),
- ('\U00000a32', '\U00000a33'),
- ('\U00000a35', '\U00000a36'),
- ('\U00000a38', '\U00000a39'),
- ('\U00000a59', '\U00000a5c'),
- ('\U00000a5e', '\U00000a5e'),
- ('\U00000a72', '\U00000a74'),
- ('\U00000a85', '\U00000a8d'),
- ('\U00000a8f', '\U00000a91'),
- ('\U00000a93', '\U00000aa8'),
- ('\U00000aaa', '\U00000ab0'),
- ('\U00000ab2', '\U00000ab3'),
- ('\U00000ab5', '\U00000ab9'),
- ('\U00000abd', '\U00000abd'),
- ('\U00000ad0', '\U00000ad0'),
- ('\U00000ae0', '\U00000ae1'),
- ('\U00000b05', '\U00000b0c'),
- ('\U00000b0f', '\U00000b10'),
- ('\U00000b13', '\U00000b28'),
- ('\U00000b2a', '\U00000b30'),
- ('\U00000b32', '\U00000b33'),
- ('\U00000b35', '\U00000b39'),
- ('\U00000b3d', '\U00000b3d'),
- ('\U00000b5c', '\U00000b5d'),
- ('\U00000b5f', '\U00000b61'),
- ('\U00000b71', '\U00000b71'),
- ('\U00000b83', '\U00000b83'),
- ('\U00000b85', '\U00000b8a'),
- ('\U00000b8e', '\U00000b90'),
- ('\U00000b92', '\U00000b95'),
- ('\U00000b99', '\U00000b9a'),
- ('\U00000b9c', '\U00000b9c'),
- ('\U00000b9e', '\U00000b9f'),
- ('\U00000ba3', '\U00000ba4'),
- ('\U00000ba8', '\U00000baa'),
- ('\U00000bae', '\U00000bb9'),
- ('\U00000bd0', '\U00000bd0'),
- ('\U00000c05', '\U00000c0c'),
- ('\U00000c0e', '\U00000c10'),
- ('\U00000c12', '\U00000c28'),
- ('\U00000c2a', '\U00000c33'),
- ('\U00000c35', '\U00000c39'),
- ('\U00000c3d', '\U00000c3d'),
- ('\U00000c58', '\U00000c59'),
- ('\U00000c60', '\U00000c61'),
- ('\U00000c85', '\U00000c8c'),
- ('\U00000c8e', '\U00000c90'),
- ('\U00000c92', '\U00000ca8'),
- ('\U00000caa', '\U00000cb3'),
- ('\U00000cb5', '\U00000cb9'),
- ('\U00000cbd', '\U00000cbd'),
- ('\U00000cde', '\U00000cde'),
- ('\U00000ce0', '\U00000ce1'),
- ('\U00000cf1', '\U00000cf2'),
- ('\U00000d05', '\U00000d0c'),
- ('\U00000d0e', '\U00000d10'),
- ('\U00000d12', '\U00000d3a'),
- ('\U00000d3d', '\U00000d3d'),
- ('\U00000d4e', '\U00000d4e'),
- ('\U00000d60', '\U00000d61'),
- ('\U00000d7a', '\U00000d7f'),
- ('\U00000d85', '\U00000d96'),
- ('\U00000d9a', '\U00000db1'),
- ('\U00000db3', '\U00000dbb'),
- ('\U00000dbd', '\U00000dbd'),
- ('\U00000dc0', '\U00000dc6'),
- ('\U00000e01', '\U00000e30'),
- ('\U00000e32', '\U00000e33'),
- ('\U00000e40', '\U00000e45'),
- ('\U00000e81', '\U00000e82'),
- ('\U00000e84', '\U00000e84'),
- ('\U00000e87', '\U00000e88'),
- ('\U00000e8a', '\U00000e8a'),
- ('\U00000e8d', '\U00000e8d'),
- ('\U00000e94', '\U00000e97'),
- ('\U00000e99', '\U00000e9f'),
- ('\U00000ea1', '\U00000ea3'),
- ('\U00000ea5', '\U00000ea5'),
- ('\U00000ea7', '\U00000ea7'),
- ('\U00000eaa', '\U00000eab'),
- ('\U00000ead', '\U00000eb0'),
- ('\U00000eb2', '\U00000eb3'),
- ('\U00000ebd', '\U00000ebd'),
- ('\U00000ec0', '\U00000ec4'),
- ('\U00000edc', '\U00000edf'),
- ('\U00000f00', '\U00000f00'),
- ('\U00000f40', '\U00000f47'),
- ('\U00000f49', '\U00000f6c'),
- ('\U00000f88', '\U00000f8c'),
- ('\U00001000', '\U0000102a'),
- ('\U0000103f', '\U0000103f'),
- ('\U00001050', '\U00001055'),
- ('\U0000105a', '\U0000105d'),
- ('\U00001061', '\U00001061'),
- ('\U00001065', '\U00001066'),
- ('\U0000106e', '\U00001070'),
- ('\U00001075', '\U00001081'),
- ('\U0000108e', '\U0000108e'),
- ('\U000010d0', '\U000010fa'),
- ('\U000010fd', '\U00001248'),
- ('\U0000124a', '\U0000124d'),
- ('\U00001250', '\U00001256'),
- ('\U00001258', '\U00001258'),
- ('\U0000125a', '\U0000125d'),
- ('\U00001260', '\U00001288'),
- ('\U0000128a', '\U0000128d'),
- ('\U00001290', '\U000012b0'),
- ('\U000012b2', '\U000012b5'),
- ('\U000012b8', '\U000012be'),
- ('\U000012c0', '\U000012c0'),
- ('\U000012c2', '\U000012c5'),
- ('\U000012c8', '\U000012d6'),
- ('\U000012d8', '\U00001310'),
- ('\U00001312', '\U00001315'),
- ('\U00001318', '\U0000135a'),
- ('\U00001380', '\U0000138f'),
- ('\U000013a0', '\U000013f4'),
- ('\U00001401', '\U0000166c'),
- ('\U0000166f', '\U0000167f'),
- ('\U00001681', '\U0000169a'),
- ('\U000016a0', '\U000016ea'),
- ('\U00001700', '\U0000170c'),
- ('\U0000170e', '\U00001711'),
- ('\U00001720', '\U00001731'),
- ('\U00001740', '\U00001751'),
- ('\U00001760', '\U0000176c'),
- ('\U0000176e', '\U00001770'),
- ('\U00001780', '\U000017b3'),
- ('\U000017dc', '\U000017dc'),
- ('\U00001820', '\U00001842'),
- ('\U00001844', '\U00001877'),
- ('\U00001880', '\U000018a8'),
- ('\U000018aa', '\U000018aa'),
- ('\U000018b0', '\U000018f5'),
- ('\U00001900', '\U0000191c'),
- ('\U00001950', '\U0000196d'),
- ('\U00001970', '\U00001974'),
- ('\U00001980', '\U000019ab'),
- ('\U000019c1', '\U000019c7'),
- ('\U00001a00', '\U00001a16'),
- ('\U00001a20', '\U00001a54'),
- ('\U00001b05', '\U00001b33'),
- ('\U00001b45', '\U00001b4b'),
- ('\U00001b83', '\U00001ba0'),
- ('\U00001bae', '\U00001baf'),
- ('\U00001bba', '\U00001be5'),
- ('\U00001c00', '\U00001c23'),
- ('\U00001c4d', '\U00001c4f'),
- ('\U00001c5a', '\U00001c77'),
- ('\U00001ce9', '\U00001cec'),
- ('\U00001cee', '\U00001cf1'),
- ('\U00001cf5', '\U00001cf6'),
- ('\U00002135', '\U00002138'),
- ('\U00002d30', '\U00002d67'),
- ('\U00002d80', '\U00002d96'),
- ('\U00002da0', '\U00002da6'),
- ('\U00002da8', '\U00002dae'),
- ('\U00002db0', '\U00002db6'),
- ('\U00002db8', '\U00002dbe'),
- ('\U00002dc0', '\U00002dc6'),
- ('\U00002dc8', '\U00002dce'),
- ('\U00002dd0', '\U00002dd6'),
- ('\U00002dd8', '\U00002dde'),
- ('\U00003006', '\U00003006'),
- ('\U0000303c', '\U0000303c'),
- ('\U00003041', '\U00003096'),
- ('\U0000309f', '\U0000309f'),
- ('\U000030a1', '\U000030fa'),
- ('\U000030ff', '\U000030ff'),
- ('\U00003105', '\U0000312d'),
- ('\U00003131', '\U0000318e'),
- ('\U000031a0', '\U000031ba'),
- ('\U000031f0', '\U000031ff'),
- ('\U00003400', '\U00003400'),
- ('\U00004db5', '\U00004db5'),
- ('\U00004e00', '\U00004e00'),
- ('\U00009fcc', '\U00009fcc'),
- ('\U0000a000', '\U0000a014'),
- ('\U0000a016', '\U0000a48c'),
- ('\U0000a4d0', '\U0000a4f7'),
- ('\U0000a500', '\U0000a60b'),
- ('\U0000a610', '\U0000a61f'),
- ('\U0000a62a', '\U0000a62b'),
- ('\U0000a66e', '\U0000a66e'),
- ('\U0000a6a0', '\U0000a6e5'),
- ('\U0000a7fb', '\U0000a801'),
- ('\U0000a803', '\U0000a805'),
- ('\U0000a807', '\U0000a80a'),
- ('\U0000a80c', '\U0000a822'),
- ('\U0000a840', '\U0000a873'),
- ('\U0000a882', '\U0000a8b3'),
- ('\U0000a8f2', '\U0000a8f7'),
- ('\U0000a8fb', '\U0000a8fb'),
- ('\U0000a90a', '\U0000a925'),
- ('\U0000a930', '\U0000a946'),
- ('\U0000a960', '\U0000a97c'),
- ('\U0000a984', '\U0000a9b2'),
- ('\U0000aa00', '\U0000aa28'),
- ('\U0000aa40', '\U0000aa42'),
- ('\U0000aa44', '\U0000aa4b'),
- ('\U0000aa60', '\U0000aa6f'),
- ('\U0000aa71', '\U0000aa76'),
- ('\U0000aa7a', '\U0000aa7a'),
- ('\U0000aa80', '\U0000aaaf'),
- ('\U0000aab1', '\U0000aab1'),
- ('\U0000aab5', '\U0000aab6'),
- ('\U0000aab9', '\U0000aabd'),
- ('\U0000aac0', '\U0000aac0'),
- ('\U0000aac2', '\U0000aac2'),
- ('\U0000aadb', '\U0000aadc'),
- ('\U0000aae0', '\U0000aaea'),
- ('\U0000aaf2', '\U0000aaf2'),
- ('\U0000ab01', '\U0000ab06'),
- ('\U0000ab09', '\U0000ab0e'),
- ('\U0000ab11', '\U0000ab16'),
- ('\U0000ab20', '\U0000ab26'),
- ('\U0000ab28', '\U0000ab2e'),
- ('\U0000abc0', '\U0000abe2'),
- ('\U0000ac00', '\U0000ac00'),
- ('\U0000d7a3', '\U0000d7a3'),
- ('\U0000d7b0', '\U0000d7c6'),
- ('\U0000d7cb', '\U0000d7fb'),
- ('\U0000f900', '\U0000fa6d'),
- ('\U0000fa70', '\U0000fad9'),
- ('\U0000fb1d', '\U0000fb1d'),
- ('\U0000fb1f', '\U0000fb28'),
- ('\U0000fb2a', '\U0000fb36'),
- ('\U0000fb38', '\U0000fb3c'),
- ('\U0000fb3e', '\U0000fb3e'),
- ('\U0000fb40', '\U0000fb41'),
- ('\U0000fb43', '\U0000fb44'),
- ('\U0000fb46', '\U0000fbb1'),
- ('\U0000fbd3', '\U0000fd3d'),
- ('\U0000fd50', '\U0000fd8f'),
- ('\U0000fd92', '\U0000fdc7'),
- ('\U0000fdf0', '\U0000fdfb'),
- ('\U0000fe70', '\U0000fe74'),
- ('\U0000fe76', '\U0000fefc'),
- ('\U0000ff66', '\U0000ff6f'),
- ('\U0000ff71', '\U0000ff9d'),
- ('\U0000ffa0', '\U0000ffbe'),
- ('\U0000ffc2', '\U0000ffc7'),
- ('\U0000ffca', '\U0000ffcf'),
- ('\U0000ffd2', '\U0000ffd7'),
- ('\U0000ffda', '\U0000ffdc'),
- ('\U00010000', '\U0001000b'),
- ('\U0001000d', '\U00010026'),
- ('\U00010028', '\U0001003a'),
- ('\U0001003c', '\U0001003d'),
- ('\U0001003f', '\U0001004d'),
- ('\U00010050', '\U0001005d'),
- ('\U00010080', '\U000100fa'),
- ('\U00010280', '\U0001029c'),
- ('\U000102a0', '\U000102d0'),
- ('\U00010300', '\U0001031e'),
- ('\U00010330', '\U00010340'),
- ('\U00010342', '\U00010349'),
- ('\U00010380', '\U0001039d'),
- ('\U000103a0', '\U000103c3'),
- ('\U000103c8', '\U000103cf'),
- ('\U00010450', '\U0001049d'),
- ('\U00010800', '\U00010805'),
- ('\U00010808', '\U00010808'),
- ('\U0001080a', '\U00010835'),
- ('\U00010837', '\U00010838'),
- ('\U0001083c', '\U0001083c'),
- ('\U0001083f', '\U00010855'),
- ('\U00010900', '\U00010915'),
- ('\U00010920', '\U00010939'),
- ('\U00010980', '\U000109b7'),
- ('\U000109be', '\U000109bf'),
- ('\U00010a00', '\U00010a00'),
- ('\U00010a10', '\U00010a13'),
- ('\U00010a15', '\U00010a17'),
- ('\U00010a19', '\U00010a33'),
- ('\U00010a60', '\U00010a7c'),
- ('\U00010b00', '\U00010b35'),
- ('\U00010b40', '\U00010b55'),
- ('\U00010b60', '\U00010b72'),
- ('\U00010c00', '\U00010c48'),
- ('\U00011003', '\U00011037'),
- ('\U00011083', '\U000110af'),
- ('\U000110d0', '\U000110e8'),
- ('\U00011103', '\U00011126'),
- ('\U00011183', '\U000111b2'),
- ('\U000111c1', '\U000111c4'),
- ('\U00011680', '\U000116aa'),
- ('\U00012000', '\U0001236e'),
- ('\U00013000', '\U0001342e'),
- ('\U00016800', '\U00016a38'),
- ('\U00016f00', '\U00016f44'),
- ('\U00016f50', '\U00016f50'),
- ('\U0001b000', '\U0001b001'),
- ('\U0001ee00', '\U0001ee03'),
- ('\U0001ee05', '\U0001ee1f'),
- ('\U0001ee21', '\U0001ee22'),
- ('\U0001ee24', '\U0001ee24'),
- ('\U0001ee27', '\U0001ee27'),
- ('\U0001ee29', '\U0001ee32'),
- ('\U0001ee34', '\U0001ee37'),
- ('\U0001ee39', '\U0001ee39'),
- ('\U0001ee3b', '\U0001ee3b'),
- ('\U0001ee42', '\U0001ee42'),
- ('\U0001ee47', '\U0001ee47'),
- ('\U0001ee49', '\U0001ee49'),
- ('\U0001ee4b', '\U0001ee4b'),
- ('\U0001ee4d', '\U0001ee4f'),
- ('\U0001ee51', '\U0001ee52'),
- ('\U0001ee54', '\U0001ee54'),
- ('\U0001ee57', '\U0001ee57'),
- ('\U0001ee59', '\U0001ee59'),
- ('\U0001ee5b', '\U0001ee5b'),
- ('\U0001ee5d', '\U0001ee5d'),
- ('\U0001ee5f', '\U0001ee5f'),
- ('\U0001ee61', '\U0001ee62'),
- ('\U0001ee64', '\U0001ee64'),
- ('\U0001ee67', '\U0001ee6a'),
- ('\U0001ee6c', '\U0001ee72'),
- ('\U0001ee74', '\U0001ee77'),
- ('\U0001ee79', '\U0001ee7c'),
- ('\U0001ee7e', '\U0001ee7e'),
- ('\U0001ee80', '\U0001ee89'),
- ('\U0001ee8b', '\U0001ee9b'),
- ('\U0001eea1', '\U0001eea3'),
- ('\U0001eea5', '\U0001eea9'),
- ('\U0001eeab', '\U0001eebb'),
- ('\U00020000', '\U00020000'),
- ('\U0002a6d6', '\U0002a6d6'),
- ('\U0002a700', '\U0002a700'),
- ('\U0002b734', '\U0002b734'),
- ('\U0002b740', '\U0002b740'),
- ('\U0002b81d', '\U0002b81d'),
- ('\U0002f800', '\U0002fa1d')
- ]),
-("Lt", &[
- ('\U000001c5', '\U000001c5'),
- ('\U000001c8', '\U000001c8'),
- ('\U000001cb', '\U000001cb'),
- ('\U000001f2', '\U000001f2'),
- ('\U00001f88', '\U00001f8f'),
- ('\U00001f98', '\U00001f9f'),
- ('\U00001fa8', '\U00001faf'),
- ('\U00001fbc', '\U00001fbc'),
- ('\U00001fcc', '\U00001fcc'),
- ('\U00001ffc', '\U00001ffc')
- ]),
-("Lu", &[
- ('\U00000041', '\U0000005a'),
- ('\U000000c0', '\U000000d6'),
- ('\U000000d8', '\U000000de'),
- ('\U00000100', '\U00000100'),
- ('\U00000102', '\U00000102'),
- ('\U00000104', '\U00000104'),
- ('\U00000106', '\U00000106'),
- ('\U00000108', '\U00000108'),
- ('\U0000010a', '\U0000010a'),
- ('\U0000010c', '\U0000010c'),
- ('\U0000010e', '\U0000010e'),
- ('\U00000110', '\U00000110'),
- ('\U00000112', '\U00000112'),
- ('\U00000114', '\U00000114'),
- ('\U00000116', '\U00000116'),
- ('\U00000118', '\U00000118'),
- ('\U0000011a', '\U0000011a'),
- ('\U0000011c', '\U0000011c'),
- ('\U0000011e', '\U0000011e'),
- ('\U00000120', '\U00000120'),
- ('\U00000122', '\U00000122'),
- ('\U00000124', '\U00000124'),
- ('\U00000126', '\U00000126'),
- ('\U00000128', '\U00000128'),
- ('\U0000012a', '\U0000012a'),
- ('\U0000012c', '\U0000012c'),
- ('\U0000012e', '\U0000012e'),
- ('\U00000130', '\U00000130'),
- ('\U00000132', '\U00000132'),
- ('\U00000134', '\U00000134'),
- ('\U00000136', '\U00000136'),
- ('\U00000139', '\U00000139'),
- ('\U0000013b', '\U0000013b'),
- ('\U0000013d', '\U0000013d'),
- ('\U0000013f', '\U0000013f'),
- ('\U00000141', '\U00000141'),
- ('\U00000143', '\U00000143'),
- ('\U00000145', '\U00000145'),
- ('\U00000147', '\U00000147'),
- ('\U0000014a', '\U0000014a'),
- ('\U0000014c', '\U0000014c'),
- ('\U0000014e', '\U0000014e'),
- ('\U00000150', '\U00000150'),
- ('\U00000152', '\U00000152'),
- ('\U00000154', '\U00000154'),
- ('\U00000156', '\U00000156'),
- ('\U00000158', '\U00000158'),
- ('\U0000015a', '\U0000015a'),
- ('\U0000015c', '\U0000015c'),
- ('\U0000015e', '\U0000015e'),
- ('\U00000160', '\U00000160'),
- ('\U00000162', '\U00000162'),
- ('\U00000164', '\U00000164'),
- ('\U00000166', '\U00000166'),
- ('\U00000168', '\U00000168'),
- ('\U0000016a', '\U0000016a'),
- ('\U0000016c', '\U0000016c'),
- ('\U0000016e', '\U0000016e'),
- ('\U00000170', '\U00000170'),
- ('\U00000172', '\U00000172'),
- ('\U00000174', '\U00000174'),
- ('\U00000176', '\U00000176'),
- ('\U00000178', '\U00000179'),
- ('\U0000017b', '\U0000017b'),
- ('\U0000017d', '\U0000017d'),
- ('\U00000181', '\U00000182'),
- ('\U00000184', '\U00000184'),
- ('\U00000186', '\U00000187'),
- ('\U00000189', '\U0000018b'),
- ('\U0000018e', '\U00000191'),
- ('\U00000193', '\U00000194'),
- ('\U00000196', '\U00000198'),
- ('\U0000019c', '\U0000019d'),
- ('\U0000019f', '\U000001a0'),
- ('\U000001a2', '\U000001a2'),
- ('\U000001a4', '\U000001a4'),
- ('\U000001a6', '\U000001a7'),
- ('\U000001a9', '\U000001a9'),
- ('\U000001ac', '\U000001ac'),
- ('\U000001ae', '\U000001af'),
- ('\U000001b1', '\U000001b3'),
- ('\U000001b5', '\U000001b5'),
- ('\U000001b7', '\U000001b8'),
- ('\U000001bc', '\U000001bc'),
- ('\U000001c4', '\U000001c4'),
- ('\U000001c7', '\U000001c7'),
- ('\U000001ca', '\U000001ca'),
- ('\U000001cd', '\U000001cd'),
- ('\U000001cf', '\U000001cf'),
- ('\U000001d1', '\U000001d1'),
- ('\U000001d3', '\U000001d3'),
- ('\U000001d5', '\U000001d5'),
- ('\U000001d7', '\U000001d7'),
- ('\U000001d9', '\U000001d9'),
- ('\U000001db', '\U000001db'),
- ('\U000001de', '\U000001de'),
- ('\U000001e0', '\U000001e0'),
- ('\U000001e2', '\U000001e2'),
- ('\U000001e4', '\U000001e4'),
- ('\U000001e6', '\U000001e6'),
- ('\U000001e8', '\U000001e8'),
- ('\U000001ea', '\U000001ea'),
- ('\U000001ec', '\U000001ec'),
- ('\U000001ee', '\U000001ee'),
- ('\U000001f1', '\U000001f1'),
- ('\U000001f4', '\U000001f4'),
- ('\U000001f6', '\U000001f8'),
- ('\U000001fa', '\U000001fa'),
- ('\U000001fc', '\U000001fc'),
- ('\U000001fe', '\U000001fe'),
- ('\U00000200', '\U00000200'),
- ('\U00000202', '\U00000202'),
- ('\U00000204', '\U00000204'),
- ('\U00000206', '\U00000206'),
- ('\U00000208', '\U00000208'),
- ('\U0000020a', '\U0000020a'),
- ('\U0000020c', '\U0000020c'),
- ('\U0000020e', '\U0000020e'),
- ('\U00000210', '\U00000210'),
- ('\U00000212', '\U00000212'),
- ('\U00000214', '\U00000214'),
- ('\U00000216', '\U00000216'),
- ('\U00000218', '\U00000218'),
- ('\U0000021a', '\U0000021a'),
- ('\U0000021c', '\U0000021c'),
- ('\U0000021e', '\U0000021e'),
- ('\U00000220', '\U00000220'),
- ('\U00000222', '\U00000222'),
- ('\U00000224', '\U00000224'),
- ('\U00000226', '\U00000226'),
- ('\U00000228', '\U00000228'),
- ('\U0000022a', '\U0000022a'),
- ('\U0000022c', '\U0000022c'),
- ('\U0000022e', '\U0000022e'),
- ('\U00000230', '\U00000230'),
- ('\U00000232', '\U00000232'),
- ('\U0000023a', '\U0000023b'),
- ('\U0000023d', '\U0000023e'),
- ('\U00000241', '\U00000241'),
- ('\U00000243', '\U00000246'),
- ('\U00000248', '\U00000248'),
- ('\U0000024a', '\U0000024a'),
- ('\U0000024c', '\U0000024c'),
- ('\U0000024e', '\U0000024e'),
- ('\U00000370', '\U00000370'),
- ('\U00000372', '\U00000372'),
- ('\U00000376', '\U00000376'),
- ('\U00000386', '\U00000386'),
- ('\U00000388', '\U0000038a'),
- ('\U0000038c', '\U0000038c'),
- ('\U0000038e', '\U0000038f'),
- ('\U00000391', '\U000003a1'),
- ('\U000003a3', '\U000003ab'),
- ('\U000003cf', '\U000003cf'),
- ('\U000003d2', '\U000003d4'),
- ('\U000003d8', '\U000003d8'),
- ('\U000003da', '\U000003da'),
- ('\U000003dc', '\U000003dc'),
- ('\U000003de', '\U000003de'),
- ('\U000003e0', '\U000003e0'),
- ('\U000003e2', '\U000003e2'),
- ('\U000003e4', '\U000003e4'),
- ('\U000003e6', '\U000003e6'),
- ('\U000003e8', '\U000003e8'),
- ('\U000003ea', '\U000003ea'),
- ('\U000003ec', '\U000003ec'),
- ('\U000003ee', '\U000003ee'),
- ('\U000003f4', '\U000003f4'),
- ('\U000003f7', '\U000003f7'),
- ('\U000003f9', '\U000003fa'),
- ('\U000003fd', '\U0000042f'),
- ('\U00000460', '\U00000460'),
- ('\U00000462', '\U00000462'),
- ('\U00000464', '\U00000464'),
- ('\U00000466', '\U00000466'),
- ('\U00000468', '\U00000468'),
- ('\U0000046a', '\U0000046a'),
- ('\U0000046c', '\U0000046c'),
- ('\U0000046e', '\U0000046e'),
- ('\U00000470', '\U00000470'),
- ('\U00000472', '\U00000472'),
- ('\U00000474', '\U00000474'),
- ('\U00000476', '\U00000476'),
- ('\U00000478', '\U00000478'),
- ('\U0000047a', '\U0000047a'),
- ('\U0000047c', '\U0000047c'),
- ('\U0000047e', '\U0000047e'),
- ('\U00000480', '\U00000480'),
- ('\U0000048a', '\U0000048a'),
- ('\U0000048c', '\U0000048c'),
- ('\U0000048e', '\U0000048e'),
- ('\U00000490', '\U00000490'),
- ('\U00000492', '\U00000492'),
- ('\U00000494', '\U00000494'),
- ('\U00000496', '\U00000496'),
- ('\U00000498', '\U00000498'),
- ('\U0000049a', '\U0000049a'),
- ('\U0000049c', '\U0000049c'),
- ('\U0000049e', '\U0000049e'),
- ('\U000004a0', '\U000004a0'),
- ('\U000004a2', '\U000004a2'),
- ('\U000004a4', '\U000004a4'),
- ('\U000004a6', '\U000004a6'),
- ('\U000004a8', '\U000004a8'),
- ('\U000004aa', '\U000004aa'),
- ('\U000004ac', '\U000004ac'),
- ('\U000004ae', '\U000004ae'),
- ('\U000004b0', '\U000004b0'),
- ('\U000004b2', '\U000004b2'),
- ('\U000004b4', '\U000004b4'),
- ('\U000004b6', '\U000004b6'),
- ('\U000004b8', '\U000004b8'),
- ('\U000004ba', '\U000004ba'),
- ('\U000004bc', '\U000004bc'),
- ('\U000004be', '\U000004be'),
- ('\U000004c0', '\U000004c1'),
- ('\U000004c3', '\U000004c3'),
- ('\U000004c5', '\U000004c5'),
- ('\U000004c7', '\U000004c7'),
- ('\U000004c9', '\U000004c9'),
- ('\U000004cb', '\U000004cb'),
- ('\U000004cd', '\U000004cd'),
- ('\U000004d0', '\U000004d0'),
- ('\U000004d2', '\U000004d2'),
- ('\U000004d4', '\U000004d4'),
- ('\U000004d6', '\U000004d6'),
- ('\U000004d8', '\U000004d8'),
- ('\U000004da', '\U000004da'),
- ('\U000004dc', '\U000004dc'),
- ('\U000004de', '\U000004de'),
- ('\U000004e0', '\U000004e0'),
- ('\U000004e2', '\U000004e2'),
- ('\U000004e4', '\U000004e4'),
- ('\U000004e6', '\U000004e6'),
- ('\U000004e8', '\U000004e8'),
- ('\U000004ea', '\U000004ea'),
- ('\U000004ec', '\U000004ec'),
- ('\U000004ee', '\U000004ee'),
- ('\U000004f0', '\U000004f0'),
- ('\U000004f2', '\U000004f2'),
- ('\U000004f4', '\U000004f4'),
- ('\U000004f6', '\U000004f6'),
- ('\U000004f8', '\U000004f8'),
- ('\U000004fa', '\U000004fa'),
- ('\U000004fc', '\U000004fc'),
- ('\U000004fe', '\U000004fe'),
- ('\U00000500', '\U00000500'),
- ('\U00000502', '\U00000502'),
- ('\U00000504', '\U00000504'),
- ('\U00000506', '\U00000506'),
- ('\U00000508', '\U00000508'),
- ('\U0000050a', '\U0000050a'),
- ('\U0000050c', '\U0000050c'),
- ('\U0000050e', '\U0000050e'),
- ('\U00000510', '\U00000510'),
- ('\U00000512', '\U00000512'),
- ('\U00000514', '\U00000514'),
- ('\U00000516', '\U00000516'),
- ('\U00000518', '\U00000518'),
- ('\U0000051a', '\U0000051a'),
- ('\U0000051c', '\U0000051c'),
- ('\U0000051e', '\U0000051e'),
- ('\U00000520', '\U00000520'),
- ('\U00000522', '\U00000522'),
- ('\U00000524', '\U00000524'),
- ('\U00000526', '\U00000526'),
- ('\U00000531', '\U00000556'),
- ('\U000010a0', '\U000010c5'),
- ('\U000010c7', '\U000010c7'),
- ('\U000010cd', '\U000010cd'),
- ('\U00001e00', '\U00001e00'),
- ('\U00001e02', '\U00001e02'),
- ('\U00001e04', '\U00001e04'),
- ('\U00001e06', '\U00001e06'),
- ('\U00001e08', '\U00001e08'),
- ('\U00001e0a', '\U00001e0a'),
- ('\U00001e0c', '\U00001e0c'),
- ('\U00001e0e', '\U00001e0e'),
- ('\U00001e10', '\U00001e10'),
- ('\U00001e12', '\U00001e12'),
- ('\U00001e14', '\U00001e14'),
- ('\U00001e16', '\U00001e16'),
- ('\U00001e18', '\U00001e18'),
- ('\U00001e1a', '\U00001e1a'),
- ('\U00001e1c', '\U00001e1c'),
- ('\U00001e1e', '\U00001e1e'),
- ('\U00001e20', '\U00001e20'),
- ('\U00001e22', '\U00001e22'),
- ('\U00001e24', '\U00001e24'),
- ('\U00001e26', '\U00001e26'),
- ('\U00001e28', '\U00001e28'),
- ('\U00001e2a', '\U00001e2a'),
- ('\U00001e2c', '\U00001e2c'),
- ('\U00001e2e', '\U00001e2e'),
- ('\U00001e30', '\U00001e30'),
- ('\U00001e32', '\U00001e32'),
- ('\U00001e34', '\U00001e34'),
- ('\U00001e36', '\U00001e36'),
- ('\U00001e38', '\U00001e38'),
- ('\U00001e3a', '\U00001e3a'),
- ('\U00001e3c', '\U00001e3c'),
- ('\U00001e3e', '\U00001e3e'),
- ('\U00001e40', '\U00001e40'),
- ('\U00001e42', '\U00001e42'),
- ('\U00001e44', '\U00001e44'),
- ('\U00001e46', '\U00001e46'),
- ('\U00001e48', '\U00001e48'),
- ('\U00001e4a', '\U00001e4a'),
- ('\U00001e4c', '\U00001e4c'),
- ('\U00001e4e', '\U00001e4e'),
- ('\U00001e50', '\U00001e50'),
- ('\U00001e52', '\U00001e52'),
- ('\U00001e54', '\U00001e54'),
- ('\U00001e56', '\U00001e56'),
- ('\U00001e58', '\U00001e58'),
- ('\U00001e5a', '\U00001e5a'),
- ('\U00001e5c', '\U00001e5c'),
- ('\U00001e5e', '\U00001e5e'),
- ('\U00001e60', '\U00001e60'),
- ('\U00001e62', '\U00001e62'),
- ('\U00001e64', '\U00001e64'),
- ('\U00001e66', '\U00001e66'),
- ('\U00001e68', '\U00001e68'),
- ('\U00001e6a', '\U00001e6a'),
- ('\U00001e6c', '\U00001e6c'),
- ('\U00001e6e', '\U00001e6e'),
- ('\U00001e70', '\U00001e70'),
- ('\U00001e72', '\U00001e72'),
- ('\U00001e74', '\U00001e74'),
- ('\U00001e76', '\U00001e76'),
- ('\U00001e78', '\U00001e78'),
- ('\U00001e7a', '\U00001e7a'),
- ('\U00001e7c', '\U00001e7c'),
- ('\U00001e7e', '\U00001e7e'),
- ('\U00001e80', '\U00001e80'),
- ('\U00001e82', '\U00001e82'),
- ('\U00001e84', '\U00001e84'),
- ('\U00001e86', '\U00001e86'),
- ('\U00001e88', '\U00001e88'),
- ('\U00001e8a', '\U00001e8a'),
- ('\U00001e8c', '\U00001e8c'),
- ('\U00001e8e', '\U00001e8e'),
- ('\U00001e90', '\U00001e90'),
- ('\U00001e92', '\U00001e92'),
- ('\U00001e94', '\U00001e94'),
- ('\U00001e9e', '\U00001e9e'),
- ('\U00001ea0', '\U00001ea0'),
- ('\U00001ea2', '\U00001ea2'),
- ('\U00001ea4', '\U00001ea4'),
- ('\U00001ea6', '\U00001ea6'),
- ('\U00001ea8', '\U00001ea8'),
- ('\U00001eaa', '\U00001eaa'),
- ('\U00001eac', '\U00001eac'),
- ('\U00001eae', '\U00001eae'),
- ('\U00001eb0', '\U00001eb0'),
- ('\U00001eb2', '\U00001eb2'),
- ('\U00001eb4', '\U00001eb4'),
- ('\U00001eb6', '\U00001eb6'),
- ('\U00001eb8', '\U00001eb8'),
- ('\U00001eba', '\U00001eba'),
- ('\U00001ebc', '\U00001ebc'),
- ('\U00001ebe', '\U00001ebe'),
- ('\U00001ec0', '\U00001ec0'),
- ('\U00001ec2', '\U00001ec2'),
- ('\U00001ec4', '\U00001ec4'),
- ('\U00001ec6', '\U00001ec6'),
- ('\U00001ec8', '\U00001ec8'),
- ('\U00001eca', '\U00001eca'),
- ('\U00001ecc', '\U00001ecc'),
- ('\U00001ece', '\U00001ece'),
- ('\U00001ed0', '\U00001ed0'),
- ('\U00001ed2', '\U00001ed2'),
- ('\U00001ed4', '\U00001ed4'),
- ('\U00001ed6', '\U00001ed6'),
- ('\U00001ed8', '\U00001ed8'),
- ('\U00001eda', '\U00001eda'),
- ('\U00001edc', '\U00001edc'),
- ('\U00001ede', '\U00001ede'),
- ('\U00001ee0', '\U00001ee0'),
- ('\U00001ee2', '\U00001ee2'),
- ('\U00001ee4', '\U00001ee4'),
- ('\U00001ee6', '\U00001ee6'),
- ('\U00001ee8', '\U00001ee8'),
- ('\U00001eea', '\U00001eea'),
- ('\U00001eec', '\U00001eec'),
- ('\U00001eee', '\U00001eee'),
- ('\U00001ef0', '\U00001ef0'),
- ('\U00001ef2', '\U00001ef2'),
- ('\U00001ef4', '\U00001ef4'),
- ('\U00001ef6', '\U00001ef6'),
- ('\U00001ef8', '\U00001ef8'),
- ('\U00001efa', '\U00001efa'),
- ('\U00001efc', '\U00001efc'),
- ('\U00001efe', '\U00001efe'),
- ('\U00001f08', '\U00001f0f'),
- ('\U00001f18', '\U00001f1d'),
- ('\U00001f28', '\U00001f2f'),
- ('\U00001f38', '\U00001f3f'),
- ('\U00001f48', '\U00001f4d'),
- ('\U00001f59', '\U00001f59'),
- ('\U00001f5b', '\U00001f5b'),
- ('\U00001f5d', '\U00001f5d'),
- ('\U00001f5f', '\U00001f5f'),
- ('\U00001f68', '\U00001f6f'),
- ('\U00001fb8', '\U00001fbb'),
- ('\U00001fc8', '\U00001fcb'),
- ('\U00001fd8', '\U00001fdb'),
- ('\U00001fe8', '\U00001fec'),
- ('\U00001ff8', '\U00001ffb'),
- ('\U00002102', '\U00002102'),
- ('\U00002107', '\U00002107'),
- ('\U0000210b', '\U0000210d'),
- ('\U00002110', '\U00002112'),
- ('\U00002115', '\U00002115'),
- ('\U00002119', '\U0000211d'),
- ('\U00002124', '\U00002124'),
- ('\U00002126', '\U00002126'),
- ('\U00002128', '\U00002128'),
- ('\U0000212a', '\U0000212d'),
- ('\U00002130', '\U00002133'),
- ('\U0000213e', '\U0000213f'),
- ('\U00002145', '\U00002145'),
- ('\U00002183', '\U00002183'),
- ('\U00002c00', '\U00002c2e'),
- ('\U00002c60', '\U00002c60'),
- ('\U00002c62', '\U00002c64'),
- ('\U00002c67', '\U00002c67'),
- ('\U00002c69', '\U00002c69'),
- ('\U00002c6b', '\U00002c6b'),
- ('\U00002c6d', '\U00002c70'),
- ('\U00002c72', '\U00002c72'),
- ('\U00002c75', '\U00002c75'),
- ('\U00002c7e', '\U00002c80'),
- ('\U00002c82', '\U00002c82'),
- ('\U00002c84', '\U00002c84'),
- ('\U00002c86', '\U00002c86'),
- ('\U00002c88', '\U00002c88'),
- ('\U00002c8a', '\U00002c8a'),
- ('\U00002c8c', '\U00002c8c'),
- ('\U00002c8e', '\U00002c8e'),
- ('\U00002c90', '\U00002c90'),
- ('\U00002c92', '\U00002c92'),
- ('\U00002c94', '\U00002c94'),
- ('\U00002c96', '\U00002c96'),
- ('\U00002c98', '\U00002c98'),
- ('\U00002c9a', '\U00002c9a'),
- ('\U00002c9c', '\U00002c9c'),
- ('\U00002c9e', '\U00002c9e'),
- ('\U00002ca0', '\U00002ca0'),
- ('\U00002ca2', '\U00002ca2'),
- ('\U00002ca4', '\U00002ca4'),
- ('\U00002ca6', '\U00002ca6'),
- ('\U00002ca8', '\U00002ca8'),
- ('\U00002caa', '\U00002caa'),
- ('\U00002cac', '\U00002cac'),
- ('\U00002cae', '\U00002cae'),
- ('\U00002cb0', '\U00002cb0'),
- ('\U00002cb2', '\U00002cb2'),
- ('\U00002cb4', '\U00002cb4'),
- ('\U00002cb6', '\U00002cb6'),
- ('\U00002cb8', '\U00002cb8'),
- ('\U00002cba', '\U00002cba'),
- ('\U00002cbc', '\U00002cbc'),
- ('\U00002cbe', '\U00002cbe'),
- ('\U00002cc0', '\U00002cc0'),
- ('\U00002cc2', '\U00002cc2'),
- ('\U00002cc4', '\U00002cc4'),
- ('\U00002cc6', '\U00002cc6'),
- ('\U00002cc8', '\U00002cc8'),
- ('\U00002cca', '\U00002cca'),
- ('\U00002ccc', '\U00002ccc'),
- ('\U00002cce', '\U00002cce'),
- ('\U00002cd0', '\U00002cd0'),
- ('\U00002cd2', '\U00002cd2'),
- ('\U00002cd4', '\U00002cd4'),
- ('\U00002cd6', '\U00002cd6'),
- ('\U00002cd8', '\U00002cd8'),
- ('\U00002cda', '\U00002cda'),
- ('\U00002cdc', '\U00002cdc'),
- ('\U00002cde', '\U00002cde'),
- ('\U00002ce0', '\U00002ce0'),
- ('\U00002ce2', '\U00002ce2'),
- ('\U00002ceb', '\U00002ceb'),
- ('\U00002ced', '\U00002ced'),
- ('\U00002cf2', '\U00002cf2'),
- ('\U0000a640', '\U0000a640'),
- ('\U0000a642', '\U0000a642'),
- ('\U0000a644', '\U0000a644'),
- ('\U0000a646', '\U0000a646'),
- ('\U0000a648', '\U0000a648'),
- ('\U0000a64a', '\U0000a64a'),
- ('\U0000a64c', '\U0000a64c'),
- ('\U0000a64e', '\U0000a64e'),
- ('\U0000a650', '\U0000a650'),
- ('\U0000a652', '\U0000a652'),
- ('\U0000a654', '\U0000a654'),
- ('\U0000a656', '\U0000a656'),
- ('\U0000a658', '\U0000a658'),
- ('\U0000a65a', '\U0000a65a'),
- ('\U0000a65c', '\U0000a65c'),
- ('\U0000a65e', '\U0000a65e'),
- ('\U0000a660', '\U0000a660'),
- ('\U0000a662', '\U0000a662'),
- ('\U0000a664', '\U0000a664'),
- ('\U0000a666', '\U0000a666'),
- ('\U0000a668', '\U0000a668'),
- ('\U0000a66a', '\U0000a66a'),
- ('\U0000a66c', '\U0000a66c'),
- ('\U0000a680', '\U0000a680'),
- ('\U0000a682', '\U0000a682'),
- ('\U0000a684', '\U0000a684'),
- ('\U0000a686', '\U0000a686'),
- ('\U0000a688', '\U0000a688'),
- ('\U0000a68a', '\U0000a68a'),
- ('\U0000a68c', '\U0000a68c'),
- ('\U0000a68e', '\U0000a68e'),
- ('\U0000a690', '\U0000a690'),
- ('\U0000a692', '\U0000a692'),
- ('\U0000a694', '\U0000a694'),
- ('\U0000a696', '\U0000a696'),
- ('\U0000a722', '\U0000a722'),
- ('\U0000a724', '\U0000a724'),
- ('\U0000a726', '\U0000a726'),
- ('\U0000a728', '\U0000a728'),
- ('\U0000a72a', '\U0000a72a'),
- ('\U0000a72c', '\U0000a72c'),
- ('\U0000a72e', '\U0000a72e'),
- ('\U0000a732', '\U0000a732'),
- ('\U0000a734', '\U0000a734'),
- ('\U0000a736', '\U0000a736'),
- ('\U0000a738', '\U0000a738'),
- ('\U0000a73a', '\U0000a73a'),
- ('\U0000a73c', '\U0000a73c'),
- ('\U0000a73e', '\U0000a73e'),
- ('\U0000a740', '\U0000a740'),
- ('\U0000a742', '\U0000a742'),
- ('\U0000a744', '\U0000a744'),
- ('\U0000a746', '\U0000a746'),
- ('\U0000a748', '\U0000a748'),
- ('\U0000a74a', '\U0000a74a'),
- ('\U0000a74c', '\U0000a74c'),
- ('\U0000a74e', '\U0000a74e'),
- ('\U0000a750', '\U0000a750'),
- ('\U0000a752', '\U0000a752'),
- ('\U0000a754', '\U0000a754'),
- ('\U0000a756', '\U0000a756'),
- ('\U0000a758', '\U0000a758'),
- ('\U0000a75a', '\U0000a75a'),
- ('\U0000a75c', '\U0000a75c'),
- ('\U0000a75e', '\U0000a75e'),
- ('\U0000a760', '\U0000a760'),
- ('\U0000a762', '\U0000a762'),
- ('\U0000a764', '\U0000a764'),
- ('\U0000a766', '\U0000a766'),
- ('\U0000a768', '\U0000a768'),
- ('\U0000a76a', '\U0000a76a'),
- ('\U0000a76c', '\U0000a76c'),
- ('\U0000a76e', '\U0000a76e'),
- ('\U0000a779', '\U0000a779'),
- ('\U0000a77b', '\U0000a77b'),
- ('\U0000a77d', '\U0000a77e'),
- ('\U0000a780', '\U0000a780'),
- ('\U0000a782', '\U0000a782'),
- ('\U0000a784', '\U0000a784'),
- ('\U0000a786', '\U0000a786'),
- ('\U0000a78b', '\U0000a78b'),
- ('\U0000a78d', '\U0000a78d'),
- ('\U0000a790', '\U0000a790'),
- ('\U0000a792', '\U0000a792'),
- ('\U0000a7a0', '\U0000a7a0'),
- ('\U0000a7a2', '\U0000a7a2'),
- ('\U0000a7a4', '\U0000a7a4'),
- ('\U0000a7a6', '\U0000a7a6'),
- ('\U0000a7a8', '\U0000a7a8'),
- ('\U0000a7aa', '\U0000a7aa'),
- ('\U0000ff21', '\U0000ff3a'),
- ('\U00010400', '\U00010427'),
- ('\U0001d400', '\U0001d419'),
- ('\U0001d434', '\U0001d44d'),
- ('\U0001d468', '\U0001d481'),
- ('\U0001d49c', '\U0001d49c'),
- ('\U0001d49e', '\U0001d49f'),
- ('\U0001d4a2', '\U0001d4a2'),
- ('\U0001d4a5', '\U0001d4a6'),
- ('\U0001d4a9', '\U0001d4ac'),
- ('\U0001d4ae', '\U0001d4b5'),
- ('\U0001d4d0', '\U0001d4e9'),
- ('\U0001d504', '\U0001d505'),
- ('\U0001d507', '\U0001d50a'),
- ('\U0001d50d', '\U0001d514'),
- ('\U0001d516', '\U0001d51c'),
- ('\U0001d538', '\U0001d539'),
- ('\U0001d53b', '\U0001d53e'),
- ('\U0001d540', '\U0001d544'),
- ('\U0001d546', '\U0001d546'),
- ('\U0001d54a', '\U0001d550'),
- ('\U0001d56c', '\U0001d585'),
- ('\U0001d5a0', '\U0001d5b9'),
- ('\U0001d5d4', '\U0001d5ed'),
- ('\U0001d608', '\U0001d621'),
- ('\U0001d63c', '\U0001d655'),
- ('\U0001d670', '\U0001d689'),
- ('\U0001d6a8', '\U0001d6c0'),
- ('\U0001d6e2', '\U0001d6fa'),
- ('\U0001d71c', '\U0001d734'),
- ('\U0001d756', '\U0001d76e'),
- ('\U0001d790', '\U0001d7a8'),
- ('\U0001d7ca', '\U0001d7ca')
- ]),
-("Lycian", &[
- ('\U00010280', '\U0001029c')
- ]),
-("Lydian", &[
- ('\U00010920', '\U00010939'),
- ('\U0001093f', '\U0001093f')
- ]),
-("M", &[
- ('\U00000300', '\U0000036f'),
- ('\U00000483', '\U00000489'),
- ('\U00000591', '\U000005bd'),
- ('\U000005bf', '\U000005bf'),
- ('\U000005c1', '\U000005c2'),
- ('\U000005c4', '\U000005c5'),
- ('\U000005c7', '\U000005c7'),
- ('\U00000610', '\U0000061a'),
- ('\U0000064b', '\U0000065f'),
- ('\U00000670', '\U00000670'),
- ('\U000006d6', '\U000006dc'),
- ('\U000006df', '\U000006e4'),
- ('\U000006e7', '\U000006e8'),
- ('\U000006ea', '\U000006ed'),
- ('\U00000711', '\U00000711'),
- ('\U00000730', '\U0000074a'),
- ('\U000007a6', '\U000007b0'),
- ('\U000007eb', '\U000007f3'),
- ('\U00000816', '\U00000819'),
- ('\U0000081b', '\U00000823'),
- ('\U00000825', '\U00000827'),
- ('\U00000829', '\U0000082d'),
- ('\U00000859', '\U0000085b'),
- ('\U000008e4', '\U000008fe'),
- ('\U00000900', '\U00000903'),
- ('\U0000093a', '\U0000093c'),
- ('\U0000093e', '\U0000094f'),
- ('\U00000951', '\U00000957'),
- ('\U00000962', '\U00000963'),
- ('\U00000981', '\U00000983'),
- ('\U000009bc', '\U000009bc'),
- ('\U000009be', '\U000009c4'),
- ('\U000009c7', '\U000009c8'),
- ('\U000009cb', '\U000009cd'),
- ('\U000009d7', '\U000009d7'),
- ('\U000009e2', '\U000009e3'),
- ('\U00000a01', '\U00000a03'),
- ('\U00000a3c', '\U00000a3c'),
- ('\U00000a3e', '\U00000a42'),
- ('\U00000a47', '\U00000a48'),
- ('\U00000a4b', '\U00000a4d'),
- ('\U00000a51', '\U00000a51'),
- ('\U00000a70', '\U00000a71'),
- ('\U00000a75', '\U00000a75'),
- ('\U00000a81', '\U00000a83'),
- ('\U00000abc', '\U00000abc'),
- ('\U00000abe', '\U00000ac5'),
- ('\U00000ac7', '\U00000ac9'),
- ('\U00000acb', '\U00000acd'),
- ('\U00000ae2', '\U00000ae3'),
- ('\U00000b01', '\U00000b03'),
- ('\U00000b3c', '\U00000b3c'),
- ('\U00000b3e', '\U00000b44'),
- ('\U00000b47', '\U00000b48'),
- ('\U00000b4b', '\U00000b4d'),
- ('\U00000b56', '\U00000b57'),
- ('\U00000b62', '\U00000b63'),
- ('\U00000b82', '\U00000b82'),
- ('\U00000bbe', '\U00000bc2'),
- ('\U00000bc6', '\U00000bc8'),
- ('\U00000bca', '\U00000bcd'),
- ('\U00000bd7', '\U00000bd7'),
- ('\U00000c01', '\U00000c03'),
- ('\U00000c3e', '\U00000c44'),
- ('\U00000c46', '\U00000c48'),
- ('\U00000c4a', '\U00000c4d'),
- ('\U00000c55', '\U00000c56'),
- ('\U00000c62', '\U00000c63'),
- ('\U00000c82', '\U00000c83'),
- ('\U00000cbc', '\U00000cbc'),
- ('\U00000cbe', '\U00000cc4'),
- ('\U00000cc6', '\U00000cc8'),
- ('\U00000cca', '\U00000ccd'),
- ('\U00000cd5', '\U00000cd6'),
- ('\U00000ce2', '\U00000ce3'),
- ('\U00000d02', '\U00000d03'),
- ('\U00000d3e', '\U00000d44'),
- ('\U00000d46', '\U00000d48'),
- ('\U00000d4a', '\U00000d4d'),
- ('\U00000d57', '\U00000d57'),
- ('\U00000d62', '\U00000d63'),
- ('\U00000d82', '\U00000d83'),
- ('\U00000dca', '\U00000dca'),
- ('\U00000dcf', '\U00000dd4'),
- ('\U00000dd6', '\U00000dd6'),
- ('\U00000dd8', '\U00000ddf'),
- ('\U00000df2', '\U00000df3'),
- ('\U00000e31', '\U00000e31'),
- ('\U00000e34', '\U00000e3a'),
- ('\U00000e47', '\U00000e4e'),
- ('\U00000eb1', '\U00000eb1'),
- ('\U00000eb4', '\U00000eb9'),
- ('\U00000ebb', '\U00000ebc'),
- ('\U00000ec8', '\U00000ecd'),
- ('\U00000f18', '\U00000f19'),
- ('\U00000f35', '\U00000f35'),
- ('\U00000f37', '\U00000f37'),
- ('\U00000f39', '\U00000f39'),
- ('\U00000f3e', '\U00000f3f'),
- ('\U00000f71', '\U00000f84'),
- ('\U00000f86', '\U00000f87'),
- ('\U00000f8d', '\U00000f97'),
- ('\U00000f99', '\U00000fbc'),
- ('\U00000fc6', '\U00000fc6'),
- ('\U0000102b', '\U0000103e'),
- ('\U00001056', '\U00001059'),
- ('\U0000105e', '\U00001060'),
- ('\U00001062', '\U00001064'),
- ('\U00001067', '\U0000106d'),
- ('\U00001071', '\U00001074'),
- ('\U00001082', '\U0000108d'),
- ('\U0000108f', '\U0000108f'),
- ('\U0000109a', '\U0000109d'),
- ('\U0000135d', '\U0000135f'),
- ('\U00001712', '\U00001714'),
- ('\U00001732', '\U00001734'),
- ('\U00001752', '\U00001753'),
- ('\U00001772', '\U00001773'),
- ('\U000017b4', '\U000017d3'),
- ('\U000017dd', '\U000017dd'),
- ('\U0000180b', '\U0000180d'),
- ('\U000018a9', '\U000018a9'),
- ('\U00001920', '\U0000192b'),
- ('\U00001930', '\U0000193b'),
- ('\U000019b0', '\U000019c0'),
- ('\U000019c8', '\U000019c9'),
- ('\U00001a17', '\U00001a1b'),
- ('\U00001a55', '\U00001a5e'),
- ('\U00001a60', '\U00001a7c'),
- ('\U00001a7f', '\U00001a7f'),
- ('\U00001b00', '\U00001b04'),
- ('\U00001b34', '\U00001b44'),
- ('\U00001b6b', '\U00001b73'),
- ('\U00001b80', '\U00001b82'),
- ('\U00001ba1', '\U00001bad'),
- ('\U00001be6', '\U00001bf3'),
- ('\U00001c24', '\U00001c37'),
- ('\U00001cd0', '\U00001cd2'),
- ('\U00001cd4', '\U00001ce8'),
- ('\U00001ced', '\U00001ced'),
- ('\U00001cf2', '\U00001cf4'),
- ('\U00001dc0', '\U00001de6'),
- ('\U00001dfc', '\U00001dff'),
- ('\U000020d0', '\U000020f0'),
- ('\U00002cef', '\U00002cf1'),
- ('\U00002d7f', '\U00002d7f'),
- ('\U00002de0', '\U00002dff'),
- ('\U0000302a', '\U0000302f'),
- ('\U00003099', '\U0000309a'),
- ('\U0000a66f', '\U0000a672'),
- ('\U0000a674', '\U0000a67d'),
- ('\U0000a69f', '\U0000a69f'),
- ('\U0000a6f0', '\U0000a6f1'),
- ('\U0000a802', '\U0000a802'),
- ('\U0000a806', '\U0000a806'),
- ('\U0000a80b', '\U0000a80b'),
- ('\U0000a823', '\U0000a827'),
- ('\U0000a880', '\U0000a881'),
- ('\U0000a8b4', '\U0000a8c4'),
- ('\U0000a8e0', '\U0000a8f1'),
- ('\U0000a926', '\U0000a92d'),
- ('\U0000a947', '\U0000a953'),
- ('\U0000a980', '\U0000a983'),
- ('\U0000a9b3', '\U0000a9c0'),
- ('\U0000aa29', '\U0000aa36'),
- ('\U0000aa43', '\U0000aa43'),
- ('\U0000aa4c', '\U0000aa4d'),
- ('\U0000aa7b', '\U0000aa7b'),
- ('\U0000aab0', '\U0000aab0'),
- ('\U0000aab2', '\U0000aab4'),
- ('\U0000aab7', '\U0000aab8'),
- ('\U0000aabe', '\U0000aabf'),
- ('\U0000aac1', '\U0000aac1'),
- ('\U0000aaeb', '\U0000aaef'),
- ('\U0000aaf5', '\U0000aaf6'),
- ('\U0000abe3', '\U0000abea'),
- ('\U0000abec', '\U0000abed'),
- ('\U0000fb1e', '\U0000fb1e'),
- ('\U0000fe00', '\U0000fe0f'),
- ('\U0000fe20', '\U0000fe26'),
- ('\U000101fd', '\U000101fd'),
- ('\U00010a01', '\U00010a03'),
- ('\U00010a05', '\U00010a06'),
- ('\U00010a0c', '\U00010a0f'),
- ('\U00010a38', '\U00010a3a'),
- ('\U00010a3f', '\U00010a3f'),
- ('\U00011000', '\U00011002'),
- ('\U00011038', '\U00011046'),
- ('\U00011080', '\U00011082'),
- ('\U000110b0', '\U000110ba'),
- ('\U00011100', '\U00011102'),
- ('\U00011127', '\U00011134'),
- ('\U00011180', '\U00011182'),
- ('\U000111b3', '\U000111c0'),
- ('\U000116ab', '\U000116b7'),
- ('\U00016f51', '\U00016f7e'),
- ('\U00016f8f', '\U00016f92'),
- ('\U0001d165', '\U0001d169'),
- ('\U0001d16d', '\U0001d172'),
- ('\U0001d17b', '\U0001d182'),
- ('\U0001d185', '\U0001d18b'),
- ('\U0001d1aa', '\U0001d1ad'),
- ('\U0001d242', '\U0001d244'),
- ('\U000e0100', '\U000e01ef')
- ]),
-("Malayalam", &[
- ('\U00000d02', '\U00000d03'),
- ('\U00000d05', '\U00000d0c'),
- ('\U00000d0e', '\U00000d10'),
- ('\U00000d12', '\U00000d3a'),
- ('\U00000d3d', '\U00000d44'),
- ('\U00000d46', '\U00000d48'),
- ('\U00000d4a', '\U00000d4e'),
- ('\U00000d57', '\U00000d57'),
- ('\U00000d60', '\U00000d63'),
- ('\U00000d66', '\U00000d75'),
- ('\U00000d79', '\U00000d7f')
- ]),
-("Mandaic", &[
- ('\U00000840', '\U0000085b'),
- ('\U0000085e', '\U0000085e')
- ]),
-("Mc", &[
- ('\U00000903', '\U00000903'),
- ('\U0000093b', '\U0000093b'),
- ('\U0000093e', '\U00000940'),
- ('\U00000949', '\U0000094c'),
- ('\U0000094e', '\U0000094f'),
- ('\U00000982', '\U00000983'),
- ('\U000009be', '\U000009c0'),
- ('\U000009c7', '\U000009c8'),
- ('\U000009cb', '\U000009cc'),
- ('\U000009d7', '\U000009d7'),
- ('\U00000a03', '\U00000a03'),
- ('\U00000a3e', '\U00000a40'),
- ('\U00000a83', '\U00000a83'),
- ('\U00000abe', '\U00000ac0'),
- ('\U00000ac9', '\U00000ac9'),
- ('\U00000acb', '\U00000acc'),
- ('\U00000b02', '\U00000b03'),
- ('\U00000b3e', '\U00000b3e'),
- ('\U00000b40', '\U00000b40'),
- ('\U00000b47', '\U00000b48'),
- ('\U00000b4b', '\U00000b4c'),
- ('\U00000b57', '\U00000b57'),
- ('\U00000bbe', '\U00000bbf'),
- ('\U00000bc1', '\U00000bc2'),
- ('\U00000bc6', '\U00000bc8'),
- ('\U00000bca', '\U00000bcc'),
- ('\U00000bd7', '\U00000bd7'),
- ('\U00000c01', '\U00000c03'),
- ('\U00000c41', '\U00000c44'),
- ('\U00000c82', '\U00000c83'),
- ('\U00000cbe', '\U00000cbe'),
- ('\U00000cc0', '\U00000cc4'),
- ('\U00000cc7', '\U00000cc8'),
- ('\U00000cca', '\U00000ccb'),
- ('\U00000cd5', '\U00000cd6'),
- ('\U00000d02', '\U00000d03'),
- ('\U00000d3e', '\U00000d40'),
- ('\U00000d46', '\U00000d48'),
- ('\U00000d4a', '\U00000d4c'),
- ('\U00000d57', '\U00000d57'),
- ('\U00000d82', '\U00000d83'),
- ('\U00000dcf', '\U00000dd1'),
- ('\U00000dd8', '\U00000ddf'),
- ('\U00000df2', '\U00000df3'),
- ('\U00000f3e', '\U00000f3f'),
- ('\U00000f7f', '\U00000f7f'),
- ('\U0000102b', '\U0000102c'),
- ('\U00001031', '\U00001031'),
- ('\U00001038', '\U00001038'),
- ('\U0000103b', '\U0000103c'),
- ('\U00001056', '\U00001057'),
- ('\U00001062', '\U00001064'),
- ('\U00001067', '\U0000106d'),
- ('\U00001083', '\U00001084'),
- ('\U00001087', '\U0000108c'),
- ('\U0000108f', '\U0000108f'),
- ('\U0000109a', '\U0000109c'),
- ('\U000017b6', '\U000017b6'),
- ('\U000017be', '\U000017c5'),
- ('\U000017c7', '\U000017c8'),
- ('\U00001923', '\U00001926'),
- ('\U00001929', '\U0000192b'),
- ('\U00001930', '\U00001931'),
- ('\U00001933', '\U00001938'),
- ('\U000019b0', '\U000019c0'),
- ('\U000019c8', '\U000019c9'),
- ('\U00001a19', '\U00001a1a'),
- ('\U00001a55', '\U00001a55'),
- ('\U00001a57', '\U00001a57'),
- ('\U00001a61', '\U00001a61'),
- ('\U00001a63', '\U00001a64'),
- ('\U00001a6d', '\U00001a72'),
- ('\U00001b04', '\U00001b04'),
- ('\U00001b35', '\U00001b35'),
- ('\U00001b3b', '\U00001b3b'),
- ('\U00001b3d', '\U00001b41'),
- ('\U00001b43', '\U00001b44'),
- ('\U00001b82', '\U00001b82'),
- ('\U00001ba1', '\U00001ba1'),
- ('\U00001ba6', '\U00001ba7'),
- ('\U00001baa', '\U00001baa'),
- ('\U00001bac', '\U00001bad'),
- ('\U00001be7', '\U00001be7'),
- ('\U00001bea', '\U00001bec'),
- ('\U00001bee', '\U00001bee'),
- ('\U00001bf2', '\U00001bf3'),
- ('\U00001c24', '\U00001c2b'),
- ('\U00001c34', '\U00001c35'),
- ('\U00001ce1', '\U00001ce1'),
- ('\U00001cf2', '\U00001cf3'),
- ('\U0000302e', '\U0000302f'),
- ('\U0000a823', '\U0000a824'),
- ('\U0000a827', '\U0000a827'),
- ('\U0000a880', '\U0000a881'),
- ('\U0000a8b4', '\U0000a8c3'),
- ('\U0000a952', '\U0000a953'),
- ('\U0000a983', '\U0000a983'),
- ('\U0000a9b4', '\U0000a9b5'),
- ('\U0000a9ba', '\U0000a9bb'),
- ('\U0000a9bd', '\U0000a9c0'),
- ('\U0000aa2f', '\U0000aa30'),
- ('\U0000aa33', '\U0000aa34'),
- ('\U0000aa4d', '\U0000aa4d'),
- ('\U0000aa7b', '\U0000aa7b'),
- ('\U0000aaeb', '\U0000aaeb'),
- ('\U0000aaee', '\U0000aaef'),
- ('\U0000aaf5', '\U0000aaf5'),
- ('\U0000abe3', '\U0000abe4'),
- ('\U0000abe6', '\U0000abe7'),
- ('\U0000abe9', '\U0000abea'),
- ('\U0000abec', '\U0000abec'),
- ('\U00011000', '\U00011000'),
- ('\U00011002', '\U00011002'),
- ('\U00011082', '\U00011082'),
- ('\U000110b0', '\U000110b2'),
- ('\U000110b7', '\U000110b8'),
- ('\U0001112c', '\U0001112c'),
- ('\U00011182', '\U00011182'),
- ('\U000111b3', '\U000111b5'),
- ('\U000111bf', '\U000111c0'),
- ('\U000116ac', '\U000116ac'),
- ('\U000116ae', '\U000116af'),
- ('\U000116b6', '\U000116b6'),
- ('\U00016f51', '\U00016f7e'),
- ('\U0001d165', '\U0001d166'),
- ('\U0001d16d', '\U0001d172')
- ]),
-("Me", &[
- ('\U00000488', '\U00000489'),
- ('\U000020dd', '\U000020e0'),
- ('\U000020e2', '\U000020e4'),
- ('\U0000a670', '\U0000a672')
- ]),
-("Meetei_Mayek", &[
- ('\U0000aae0', '\U0000aaf6'),
- ('\U0000abc0', '\U0000abed'),
- ('\U0000abf0', '\U0000abf9')
- ]),
-("Meroitic_Cursive", &[
- ('\U000109a0', '\U000109b7'),
- ('\U000109be', '\U000109bf')
- ]),
-("Meroitic_Hieroglyphs", &[
- ('\U00010980', '\U0001099f')
- ]),
-("Miao", &[
- ('\U00016f00', '\U00016f44'),
- ('\U00016f50', '\U00016f7e'),
- ('\U00016f8f', '\U00016f9f')
- ]),
-("Mn", &[
- ('\U00000300', '\U0000036f'),
- ('\U00000483', '\U00000487'),
- ('\U00000591', '\U000005bd'),
- ('\U000005bf', '\U000005bf'),
- ('\U000005c1', '\U000005c2'),
- ('\U000005c4', '\U000005c5'),
- ('\U000005c7', '\U000005c7'),
- ('\U00000610', '\U0000061a'),
- ('\U0000064b', '\U0000065f'),
- ('\U00000670', '\U00000670'),
- ('\U000006d6', '\U000006dc'),
- ('\U000006df', '\U000006e4'),
- ('\U000006e7', '\U000006e8'),
- ('\U000006ea', '\U000006ed'),
- ('\U00000711', '\U00000711'),
- ('\U00000730', '\U0000074a'),
- ('\U000007a6', '\U000007b0'),
- ('\U000007eb', '\U000007f3'),
- ('\U00000816', '\U00000819'),
- ('\U0000081b', '\U00000823'),
- ('\U00000825', '\U00000827'),
- ('\U00000829', '\U0000082d'),
- ('\U00000859', '\U0000085b'),
- ('\U000008e4', '\U000008fe'),
- ('\U00000900', '\U00000902'),
- ('\U0000093a', '\U0000093a'),
- ('\U0000093c', '\U0000093c'),
- ('\U00000941', '\U00000948'),
- ('\U0000094d', '\U0000094d'),
- ('\U00000951', '\U00000957'),
- ('\U00000962', '\U00000963'),
- ('\U00000981', '\U00000981'),
- ('\U000009bc', '\U000009bc'),
- ('\U000009c1', '\U000009c4'),
- ('\U000009cd', '\U000009cd'),
- ('\U000009e2', '\U000009e3'),
- ('\U00000a01', '\U00000a02'),
- ('\U00000a3c', '\U00000a3c'),
- ('\U00000a41', '\U00000a42'),
- ('\U00000a47', '\U00000a48'),
- ('\U00000a4b', '\U00000a4d'),
- ('\U00000a51', '\U00000a51'),
- ('\U00000a70', '\U00000a71'),
- ('\U00000a75', '\U00000a75'),
- ('\U00000a81', '\U00000a82'),
- ('\U00000abc', '\U00000abc'),
- ('\U00000ac1', '\U00000ac5'),
- ('\U00000ac7', '\U00000ac8'),
- ('\U00000acd', '\U00000acd'),
- ('\U00000ae2', '\U00000ae3'),
- ('\U00000b01', '\U00000b01'),
- ('\U00000b3c', '\U00000b3c'),
- ('\U00000b3f', '\U00000b3f'),
- ('\U00000b41', '\U00000b44'),
- ('\U00000b4d', '\U00000b4d'),
- ('\U00000b56', '\U00000b56'),
- ('\U00000b62', '\U00000b63'),
- ('\U00000b82', '\U00000b82'),
- ('\U00000bc0', '\U00000bc0'),
- ('\U00000bcd', '\U00000bcd'),
- ('\U00000c3e', '\U00000c40'),
- ('\U00000c46', '\U00000c48'),
- ('\U00000c4a', '\U00000c4d'),
- ('\U00000c55', '\U00000c56'),
- ('\U00000c62', '\U00000c63'),
- ('\U00000cbc', '\U00000cbc'),
- ('\U00000cbf', '\U00000cbf'),
- ('\U00000cc6', '\U00000cc6'),
- ('\U00000ccc', '\U00000ccd'),
- ('\U00000ce2', '\U00000ce3'),
- ('\U00000d41', '\U00000d44'),
- ('\U00000d4d', '\U00000d4d'),
- ('\U00000d62', '\U00000d63'),
- ('\U00000dca', '\U00000dca'),
- ('\U00000dd2', '\U00000dd4'),
- ('\U00000dd6', '\U00000dd6'),
- ('\U00000e31', '\U00000e31'),
- ('\U00000e34', '\U00000e3a'),
- ('\U00000e47', '\U00000e4e'),
- ('\U00000eb1', '\U00000eb1'),
- ('\U00000eb4', '\U00000eb9'),
- ('\U00000ebb', '\U00000ebc'),
- ('\U00000ec8', '\U00000ecd'),
- ('\U00000f18', '\U00000f19'),
- ('\U00000f35', '\U00000f35'),
- ('\U00000f37', '\U00000f37'),
- ('\U00000f39', '\U00000f39'),
- ('\U00000f71', '\U00000f7e'),
- ('\U00000f80', '\U00000f84'),
- ('\U00000f86', '\U00000f87'),
- ('\U00000f8d', '\U00000f97'),
- ('\U00000f99', '\U00000fbc'),
- ('\U00000fc6', '\U00000fc6'),
- ('\U0000102d', '\U00001030'),
- ('\U00001032', '\U00001037'),
- ('\U00001039', '\U0000103a'),
- ('\U0000103d', '\U0000103e'),
- ('\U00001058', '\U00001059'),
- ('\U0000105e', '\U00001060'),
- ('\U00001071', '\U00001074'),
- ('\U00001082', '\U00001082'),
- ('\U00001085', '\U00001086'),
- ('\U0000108d', '\U0000108d'),
- ('\U0000109d', '\U0000109d'),
- ('\U0000135d', '\U0000135f'),
- ('\U00001712', '\U00001714'),
- ('\U00001732', '\U00001734'),
- ('\U00001752', '\U00001753'),
- ('\U00001772', '\U00001773'),
- ('\U000017b4', '\U000017b5'),
- ('\U000017b7', '\U000017bd'),
- ('\U000017c6', '\U000017c6'),
- ('\U000017c9', '\U000017d3'),
- ('\U000017dd', '\U000017dd'),
- ('\U0000180b', '\U0000180d'),
- ('\U000018a9', '\U000018a9'),
- ('\U00001920', '\U00001922'),
- ('\U00001927', '\U00001928'),
- ('\U00001932', '\U00001932'),
- ('\U00001939', '\U0000193b'),
- ('\U00001a17', '\U00001a18'),
- ('\U00001a1b', '\U00001a1b'),
- ('\U00001a56', '\U00001a56'),
- ('\U00001a58', '\U00001a5e'),
- ('\U00001a60', '\U00001a60'),
- ('\U00001a62', '\U00001a62'),
- ('\U00001a65', '\U00001a6c'),
- ('\U00001a73', '\U00001a7c'),
- ('\U00001a7f', '\U00001a7f'),
- ('\U00001b00', '\U00001b03'),
- ('\U00001b34', '\U00001b34'),
- ('\U00001b36', '\U00001b3a'),
- ('\U00001b3c', '\U00001b3c'),
- ('\U00001b42', '\U00001b42'),
- ('\U00001b6b', '\U00001b73'),
- ('\U00001b80', '\U00001b81'),
- ('\U00001ba2', '\U00001ba5'),
- ('\U00001ba8', '\U00001ba9'),
- ('\U00001bab', '\U00001bab'),
- ('\U00001be6', '\U00001be6'),
- ('\U00001be8', '\U00001be9'),
- ('\U00001bed', '\U00001bed'),
- ('\U00001bef', '\U00001bf1'),
- ('\U00001c2c', '\U00001c33'),
- ('\U00001c36', '\U00001c37'),
- ('\U00001cd0', '\U00001cd2'),
- ('\U00001cd4', '\U00001ce0'),
- ('\U00001ce2', '\U00001ce8'),
- ('\U00001ced', '\U00001ced'),
- ('\U00001cf4', '\U00001cf4'),
- ('\U00001dc0', '\U00001de6'),
- ('\U00001dfc', '\U00001dff'),
- ('\U000020d0', '\U000020dc'),
- ('\U000020e1', '\U000020e1'),
- ('\U000020e5', '\U000020f0'),
- ('\U00002cef', '\U00002cf1'),
- ('\U00002d7f', '\U00002d7f'),
- ('\U00002de0', '\U00002dff'),
- ('\U0000302a', '\U0000302d'),
- ('\U00003099', '\U0000309a'),
- ('\U0000a66f', '\U0000a66f'),
- ('\U0000a674', '\U0000a67d'),
- ('\U0000a69f', '\U0000a69f'),
- ('\U0000a6f0', '\U0000a6f1'),
- ('\U0000a802', '\U0000a802'),
- ('\U0000a806', '\U0000a806'),
- ('\U0000a80b', '\U0000a80b'),
- ('\U0000a825', '\U0000a826'),
- ('\U0000a8c4', '\U0000a8c4'),
- ('\U0000a8e0', '\U0000a8f1'),
- ('\U0000a926', '\U0000a92d'),
- ('\U0000a947', '\U0000a951'),
- ('\U0000a980', '\U0000a982'),
- ('\U0000a9b3', '\U0000a9b3'),
- ('\U0000a9b6', '\U0000a9b9'),
- ('\U0000a9bc', '\U0000a9bc'),
- ('\U0000aa29', '\U0000aa2e'),
- ('\U0000aa31', '\U0000aa32'),
- ('\U0000aa35', '\U0000aa36'),
- ('\U0000aa43', '\U0000aa43'),
- ('\U0000aa4c', '\U0000aa4c'),
- ('\U0000aab0', '\U0000aab0'),
- ('\U0000aab2', '\U0000aab4'),
- ('\U0000aab7', '\U0000aab8'),
- ('\U0000aabe', '\U0000aabf'),
- ('\U0000aac1', '\U0000aac1'),
- ('\U0000aaec', '\U0000aaed'),
- ('\U0000aaf6', '\U0000aaf6'),
- ('\U0000abe5', '\U0000abe5'),
- ('\U0000abe8', '\U0000abe8'),
- ('\U0000abed', '\U0000abed'),
- ('\U0000fb1e', '\U0000fb1e'),
- ('\U0000fe00', '\U0000fe0f'),
- ('\U0000fe20', '\U0000fe26'),
- ('\U000101fd', '\U000101fd'),
- ('\U00010a01', '\U00010a03'),
- ('\U00010a05', '\U00010a06'),
- ('\U00010a0c', '\U00010a0f'),
- ('\U00010a38', '\U00010a3a'),
- ('\U00010a3f', '\U00010a3f'),
- ('\U00011001', '\U00011001'),
- ('\U00011038', '\U00011046'),
- ('\U00011080', '\U00011081'),
- ('\U000110b3', '\U000110b6'),
- ('\U000110b9', '\U000110ba'),
- ('\U00011100', '\U00011102'),
- ('\U00011127', '\U0001112b'),
- ('\U0001112d', '\U00011134'),
- ('\U00011180', '\U00011181'),
- ('\U000111b6', '\U000111be'),
- ('\U000116ab', '\U000116ab'),
- ('\U000116ad', '\U000116ad'),
- ('\U000116b0', '\U000116b5'),
- ('\U000116b7', '\U000116b7'),
- ('\U00016f8f', '\U00016f92'),
- ('\U0001d167', '\U0001d169'),
- ('\U0001d17b', '\U0001d182'),
- ('\U0001d185', '\U0001d18b'),
- ('\U0001d1aa', '\U0001d1ad'),
- ('\U0001d242', '\U0001d244'),
- ('\U000e0100', '\U000e01ef')
- ]),
-("Mongolian", &[
- ('\U00001800', '\U00001801'),
- ('\U00001804', '\U00001804'),
- ('\U00001806', '\U0000180e'),
- ('\U00001810', '\U00001819'),
- ('\U00001820', '\U00001877'),
- ('\U00001880', '\U000018aa')
- ]),
-("Myanmar", &[
- ('\U00001000', '\U0000109f'),
- ('\U0000aa60', '\U0000aa7b')
- ]),
-("N", &[
- ('\U00000030', '\U00000039'),
- ('\U00000660', '\U00000669'),
- ('\U000006f0', '\U000006f9'),
- ('\U000007c0', '\U000007c9'),
- ('\U00000966', '\U0000096f'),
- ('\U000009e6', '\U000009ef'),
- ('\U00000a66', '\U00000a6f'),
- ('\U00000ae6', '\U00000aef'),
- ('\U00000b66', '\U00000b6f'),
- ('\U00000be6', '\U00000bef'),
- ('\U00000c66', '\U00000c6f'),
- ('\U00000ce6', '\U00000cef'),
- ('\U00000d66', '\U00000d6f'),
- ('\U00000e50', '\U00000e59'),
- ('\U00000ed0', '\U00000ed9'),
- ('\U00000f20', '\U00000f29'),
- ('\U00001040', '\U00001049'),
- ('\U00001090', '\U00001099'),
- ('\U000016ee', '\U000016f0'),
- ('\U000017e0', '\U000017e9'),
- ('\U00001810', '\U00001819'),
- ('\U00001946', '\U0000194f'),
- ('\U000019d0', '\U000019d9'),
- ('\U00001a80', '\U00001a89'),
- ('\U00001a90', '\U00001a99'),
- ('\U00001b50', '\U00001b59'),
- ('\U00001bb0', '\U00001bb9'),
- ('\U00001c40', '\U00001c49'),
- ('\U00001c50', '\U00001c59'),
- ('\U00002160', '\U00002182'),
- ('\U00002185', '\U00002188'),
- ('\U00003007', '\U00003007'),
- ('\U00003021', '\U00003029'),
- ('\U00003038', '\U0000303a'),
- ('\U0000a620', '\U0000a629'),
- ('\U0000a6e6', '\U0000a6ef'),
- ('\U0000a8d0', '\U0000a8d9'),
- ('\U0000a900', '\U0000a909'),
- ('\U0000a9d0', '\U0000a9d9'),
- ('\U0000aa50', '\U0000aa59'),
- ('\U0000abf0', '\U0000abf9'),
- ('\U0000ff10', '\U0000ff19'),
- ('\U00010140', '\U00010174'),
- ('\U00010341', '\U00010341'),
- ('\U0001034a', '\U0001034a'),
- ('\U000103d1', '\U000103d5'),
- ('\U000104a0', '\U000104a9'),
- ('\U00011066', '\U0001106f'),
- ('\U000110f0', '\U000110f9'),
- ('\U00011136', '\U0001113f'),
- ('\U000111d0', '\U000111d9'),
- ('\U000116c0', '\U000116c9'),
- ('\U00012400', '\U00012462'),
- ('\U0001d7ce', '\U0001d7ff')
- ]),
-("Nd", &[
- ('\U00000030', '\U00000039'),
- ('\U00000660', '\U00000669'),
- ('\U000006f0', '\U000006f9'),
- ('\U000007c0', '\U000007c9'),
- ('\U00000966', '\U0000096f'),
- ('\U000009e6', '\U000009ef'),
- ('\U00000a66', '\U00000a6f'),
- ('\U00000ae6', '\U00000aef'),
- ('\U00000b66', '\U00000b6f'),
- ('\U00000be6', '\U00000bef'),
- ('\U00000c66', '\U00000c6f'),
- ('\U00000ce6', '\U00000cef'),
- ('\U00000d66', '\U00000d6f'),
- ('\U00000e50', '\U00000e59'),
- ('\U00000ed0', '\U00000ed9'),
- ('\U00000f20', '\U00000f29'),
- ('\U00001040', '\U00001049'),
- ('\U00001090', '\U00001099'),
- ('\U000017e0', '\U000017e9'),
- ('\U00001810', '\U00001819'),
- ('\U00001946', '\U0000194f'),
- ('\U000019d0', '\U000019d9'),
- ('\U00001a80', '\U00001a89'),
- ('\U00001a90', '\U00001a99'),
- ('\U00001b50', '\U00001b59'),
- ('\U00001bb0', '\U00001bb9'),
- ('\U00001c40', '\U00001c49'),
- ('\U00001c50', '\U00001c59'),
- ('\U0000a620', '\U0000a629'),
- ('\U0000a8d0', '\U0000a8d9'),
- ('\U0000a900', '\U0000a909'),
- ('\U0000a9d0', '\U0000a9d9'),
- ('\U0000aa50', '\U0000aa59'),
- ('\U0000abf0', '\U0000abf9'),
- ('\U0000ff10', '\U0000ff19'),
- ('\U000104a0', '\U000104a9'),
- ('\U00011066', '\U0001106f'),
- ('\U000110f0', '\U000110f9'),
- ('\U00011136', '\U0001113f'),
- ('\U000111d0', '\U000111d9'),
- ('\U000116c0', '\U000116c9'),
- ('\U0001d7ce', '\U0001d7ff')
- ]),
-("New_Tai_Lue", &[
- ('\U00001980', '\U000019ab'),
- ('\U000019b0', '\U000019c9'),
- ('\U000019d0', '\U000019da'),
- ('\U000019de', '\U000019df')
- ]),
-("Nko", &[
- ('\U000007c0', '\U000007fa')
- ]),
-("Nl", &[
- ('\U000016ee', '\U000016f0'),
- ('\U00002160', '\U00002182'),
- ('\U00002185', '\U00002188'),
- ('\U00003007', '\U00003007'),
- ('\U00003021', '\U00003029'),
- ('\U00003038', '\U0000303a'),
- ('\U0000a6e6', '\U0000a6ef'),
- ('\U00010140', '\U00010174'),
- ('\U00010341', '\U00010341'),
- ('\U0001034a', '\U0001034a'),
- ('\U000103d1', '\U000103d5'),
- ('\U00012400', '\U00012462')
- ]),
-("No", &[
- ('\U000000b2', '\U000000b3'),
- ('\U000000b9', '\U000000b9'),
- ('\U000000bc', '\U000000be'),
- ('\U000009f4', '\U000009f9'),
- ('\U00000b72', '\U00000b77'),
- ('\U00000bf0', '\U00000bf2'),
- ('\U00000c78', '\U00000c7e'),
- ('\U00000d70', '\U00000d75'),
- ('\U00000f2a', '\U00000f33'),
- ('\U00001369', '\U0000137c'),
- ('\U000017f0', '\U000017f9'),
- ('\U000019da', '\U000019da'),
- ('\U00002070', '\U00002070'),
- ('\U00002074', '\U00002079'),
- ('\U00002080', '\U00002089'),
- ('\U00002150', '\U0000215f'),
- ('\U00002189', '\U00002189'),
- ('\U00002460', '\U0000249b'),
- ('\U000024ea', '\U000024ff'),
- ('\U00002776', '\U00002793'),
- ('\U00002cfd', '\U00002cfd'),
- ('\U00003192', '\U00003195'),
- ('\U00003220', '\U00003229'),
- ('\U00003248', '\U0000324f'),
- ('\U00003251', '\U0000325f'),
- ('\U00003280', '\U00003289'),
- ('\U000032b1', '\U000032bf'),
- ('\U0000a830', '\U0000a835'),
- ('\U00010107', '\U00010133'),
- ('\U00010175', '\U00010178'),
- ('\U0001018a', '\U0001018a'),
- ('\U00010320', '\U00010323'),
- ('\U00010858', '\U0001085f'),
- ('\U00010916', '\U0001091b'),
- ('\U00010a40', '\U00010a47'),
- ('\U00010a7d', '\U00010a7e'),
- ('\U00010b58', '\U00010b5f'),
- ('\U00010b78', '\U00010b7f'),
- ('\U00010e60', '\U00010e7e'),
- ('\U00011052', '\U00011065'),
- ('\U0001d360', '\U0001d371'),
- ('\U0001f100', '\U0001f10a')
- ]),
-("Ogham", &[
- ('\U00001680', '\U0000169c')
- ]),
-("Ol_Chiki", &[
- ('\U00001c50', '\U00001c7f')
- ]),
-("Old_Italic", &[
- ('\U00010300', '\U0001031e'),
- ('\U00010320', '\U00010323')
- ]),
-("Old_Persian", &[
- ('\U000103a0', '\U000103c3'),
- ('\U000103c8', '\U000103d5')
- ]),
-("Old_South_Arabian", &[
- ('\U00010a60', '\U00010a7f')
- ]),
-("Old_Turkic", &[
- ('\U00010c00', '\U00010c48')
- ]),
-("Oriya", &[
- ('\U00000b01', '\U00000b03'),
- ('\U00000b05', '\U00000b0c'),
- ('\U00000b0f', '\U00000b10'),
- ('\U00000b13', '\U00000b28'),
- ('\U00000b2a', '\U00000b30'),
- ('\U00000b32', '\U00000b33'),
- ('\U00000b35', '\U00000b39'),
- ('\U00000b3c', '\U00000b44'),
- ('\U00000b47', '\U00000b48'),
- ('\U00000b4b', '\U00000b4d'),
- ('\U00000b56', '\U00000b57'),
- ('\U00000b5c', '\U00000b5d'),
- ('\U00000b5f', '\U00000b63'),
- ('\U00000b66', '\U00000b77')
- ]),
-("Osmanya", &[
- ('\U00010480', '\U0001049d'),
- ('\U000104a0', '\U000104a9')
- ]),
-("P", &[
- ('\U00000021', '\U00000023'),
- ('\U00000025', '\U0000002a'),
- ('\U0000002c', '\U0000002f'),
- ('\U0000003a', '\U0000003b'),
- ('\U0000003f', '\U00000040'),
- ('\U0000005b', '\U0000005d'),
- ('\U0000005f', '\U0000005f'),
- ('\U0000007b', '\U0000007b'),
- ('\U0000007d', '\U0000007d'),
- ('\U000000a1', '\U000000a1'),
- ('\U000000a7', '\U000000a7'),
- ('\U000000ab', '\U000000ab'),
- ('\U000000b6', '\U000000b7'),
- ('\U000000bb', '\U000000bb'),
- ('\U000000bf', '\U000000bf'),
- ('\U0000037e', '\U0000037e'),
- ('\U00000387', '\U00000387'),
- ('\U0000055a', '\U0000055f'),
- ('\U00000589', '\U0000058a'),
- ('\U000005be', '\U000005be'),
- ('\U000005c0', '\U000005c0'),
- ('\U000005c3', '\U000005c3'),
- ('\U000005c6', '\U000005c6'),
- ('\U000005f3', '\U000005f4'),
- ('\U00000609', '\U0000060a'),
- ('\U0000060c', '\U0000060d'),
- ('\U0000061b', '\U0000061b'),
- ('\U0000061e', '\U0000061f'),
- ('\U0000066a', '\U0000066d'),
- ('\U000006d4', '\U000006d4'),
- ('\U00000700', '\U0000070d'),
- ('\U000007f7', '\U000007f9'),
- ('\U00000830', '\U0000083e'),
- ('\U0000085e', '\U0000085e'),
- ('\U00000964', '\U00000965'),
- ('\U00000970', '\U00000970'),
- ('\U00000af0', '\U00000af0'),
- ('\U00000df4', '\U00000df4'),
- ('\U00000e4f', '\U00000e4f'),
- ('\U00000e5a', '\U00000e5b'),
- ('\U00000f04', '\U00000f12'),
- ('\U00000f14', '\U00000f14'),
- ('\U00000f3a', '\U00000f3d'),
- ('\U00000f85', '\U00000f85'),
- ('\U00000fd0', '\U00000fd4'),
- ('\U00000fd9', '\U00000fda'),
- ('\U0000104a', '\U0000104f'),
- ('\U000010fb', '\U000010fb'),
- ('\U00001360', '\U00001368'),
- ('\U00001400', '\U00001400'),
- ('\U0000166d', '\U0000166e'),
- ('\U0000169b', '\U0000169c'),
- ('\U000016eb', '\U000016ed'),
- ('\U00001735', '\U00001736'),
- ('\U000017d4', '\U000017d6'),
- ('\U000017d8', '\U000017da'),
- ('\U00001800', '\U0000180a'),
- ('\U00001944', '\U00001945'),
- ('\U00001a1e', '\U00001a1f'),
- ('\U00001aa0', '\U00001aa6'),
- ('\U00001aa8', '\U00001aad'),
- ('\U00001b5a', '\U00001b60'),
- ('\U00001bfc', '\U00001bff'),
- ('\U00001c3b', '\U00001c3f'),
- ('\U00001c7e', '\U00001c7f'),
- ('\U00001cc0', '\U00001cc7'),
- ('\U00001cd3', '\U00001cd3'),
- ('\U00002010', '\U00002027'),
- ('\U00002030', '\U00002043'),
- ('\U00002045', '\U00002051'),
- ('\U00002053', '\U0000205e'),
- ('\U0000207d', '\U0000207e'),
- ('\U0000208d', '\U0000208e'),
- ('\U00002308', '\U0000230b'),
- ('\U00002329', '\U0000232a'),
- ('\U00002768', '\U00002775'),
- ('\U000027c5', '\U000027c6'),
- ('\U000027e6', '\U000027ef'),
- ('\U00002983', '\U00002998'),
- ('\U000029d8', '\U000029db'),
- ('\U000029fc', '\U000029fd'),
- ('\U00002cf9', '\U00002cfc'),
- ('\U00002cfe', '\U00002cff'),
- ('\U00002d70', '\U00002d70'),
- ('\U00002e00', '\U00002e2e'),
- ('\U00002e30', '\U00002e3b'),
- ('\U00003001', '\U00003003'),
- ('\U00003008', '\U00003011'),
- ('\U00003014', '\U0000301f'),
- ('\U00003030', '\U00003030'),
- ('\U0000303d', '\U0000303d'),
- ('\U000030a0', '\U000030a0'),
- ('\U000030fb', '\U000030fb'),
- ('\U0000a4fe', '\U0000a4ff'),
- ('\U0000a60d', '\U0000a60f'),
- ('\U0000a673', '\U0000a673'),
- ('\U0000a67e', '\U0000a67e'),
- ('\U0000a6f2', '\U0000a6f7'),
- ('\U0000a874', '\U0000a877'),
- ('\U0000a8ce', '\U0000a8cf'),
- ('\U0000a8f8', '\U0000a8fa'),
- ('\U0000a92e', '\U0000a92f'),
- ('\U0000a95f', '\U0000a95f'),
- ('\U0000a9c1', '\U0000a9cd'),
- ('\U0000a9de', '\U0000a9df'),
- ('\U0000aa5c', '\U0000aa5f'),
- ('\U0000aade', '\U0000aadf'),
- ('\U0000aaf0', '\U0000aaf1'),
- ('\U0000abeb', '\U0000abeb'),
- ('\U0000fd3e', '\U0000fd3f'),
- ('\U0000fe10', '\U0000fe19'),
- ('\U0000fe30', '\U0000fe52'),
- ('\U0000fe54', '\U0000fe61'),
- ('\U0000fe63', '\U0000fe63'),
- ('\U0000fe68', '\U0000fe68'),
- ('\U0000fe6a', '\U0000fe6b'),
- ('\U0000ff01', '\U0000ff03'),
- ('\U0000ff05', '\U0000ff0a'),
- ('\U0000ff0c', '\U0000ff0f'),
- ('\U0000ff1a', '\U0000ff1b'),
- ('\U0000ff1f', '\U0000ff20'),
- ('\U0000ff3b', '\U0000ff3d'),
- ('\U0000ff3f', '\U0000ff3f'),
- ('\U0000ff5b', '\U0000ff5b'),
- ('\U0000ff5d', '\U0000ff5d'),
- ('\U0000ff5f', '\U0000ff65'),
- ('\U00010100', '\U00010102'),
- ('\U0001039f', '\U0001039f'),
- ('\U000103d0', '\U000103d0'),
- ('\U00010857', '\U00010857'),
- ('\U0001091f', '\U0001091f'),
- ('\U0001093f', '\U0001093f'),
- ('\U00010a50', '\U00010a58'),
- ('\U00010a7f', '\U00010a7f'),
- ('\U00010b39', '\U00010b3f'),
- ('\U00011047', '\U0001104d'),
- ('\U000110bb', '\U000110bc'),
- ('\U000110be', '\U000110c1'),
- ('\U00011140', '\U00011143'),
- ('\U000111c5', '\U000111c8'),
- ('\U00012470', '\U00012473')
- ]),
-("Pc", &[
- ('\U0000005f', '\U0000005f'),
- ('\U0000203f', '\U00002040'),
- ('\U00002054', '\U00002054'),
- ('\U0000fe33', '\U0000fe34'),
- ('\U0000fe4d', '\U0000fe4f'),
- ('\U0000ff3f', '\U0000ff3f')
- ]),
-("Pd", &[
- ('\U0000002d', '\U0000002d'),
- ('\U0000058a', '\U0000058a'),
- ('\U000005be', '\U000005be'),
- ('\U00001400', '\U00001400'),
- ('\U00001806', '\U00001806'),
- ('\U00002010', '\U00002015'),
- ('\U00002e17', '\U00002e17'),
- ('\U00002e1a', '\U00002e1a'),
- ('\U00002e3a', '\U00002e3b'),
- ('\U0000301c', '\U0000301c'),
- ('\U00003030', '\U00003030'),
- ('\U000030a0', '\U000030a0'),
- ('\U0000fe31', '\U0000fe32'),
- ('\U0000fe58', '\U0000fe58'),
- ('\U0000fe63', '\U0000fe63'),
- ('\U0000ff0d', '\U0000ff0d')
- ]),
-("Pe", &[
- ('\U00000029', '\U00000029'),
- ('\U0000005d', '\U0000005d'),
- ('\U0000007d', '\U0000007d'),
- ('\U00000f3b', '\U00000f3b'),
- ('\U00000f3d', '\U00000f3d'),
- ('\U0000169c', '\U0000169c'),
- ('\U00002046', '\U00002046'),
- ('\U0000207e', '\U0000207e'),
- ('\U0000208e', '\U0000208e'),
- ('\U00002309', '\U00002309'),
- ('\U0000230b', '\U0000230b'),
- ('\U0000232a', '\U0000232a'),
- ('\U00002769', '\U00002769'),
- ('\U0000276b', '\U0000276b'),
- ('\U0000276d', '\U0000276d'),
- ('\U0000276f', '\U0000276f'),
- ('\U00002771', '\U00002771'),
- ('\U00002773', '\U00002773'),
- ('\U00002775', '\U00002775'),
- ('\U000027c6', '\U000027c6'),
- ('\U000027e7', '\U000027e7'),
- ('\U000027e9', '\U000027e9'),
- ('\U000027eb', '\U000027eb'),
- ('\U000027ed', '\U000027ed'),
- ('\U000027ef', '\U000027ef'),
- ('\U00002984', '\U00002984'),
- ('\U00002986', '\U00002986'),
- ('\U00002988', '\U00002988'),
- ('\U0000298a', '\U0000298a'),
- ('\U0000298c', '\U0000298c'),
- ('\U0000298e', '\U0000298e'),
- ('\U00002990', '\U00002990'),
- ('\U00002992', '\U00002992'),
- ('\U00002994', '\U00002994'),
- ('\U00002996', '\U00002996'),
- ('\U00002998', '\U00002998'),
- ('\U000029d9', '\U000029d9'),
- ('\U000029db', '\U000029db'),
- ('\U000029fd', '\U000029fd'),
- ('\U00002e23', '\U00002e23'),
- ('\U00002e25', '\U00002e25'),
- ('\U00002e27', '\U00002e27'),
- ('\U00002e29', '\U00002e29'),
- ('\U00003009', '\U00003009'),
- ('\U0000300b', '\U0000300b'),
- ('\U0000300d', '\U0000300d'),
- ('\U0000300f', '\U0000300f'),
- ('\U00003011', '\U00003011'),
- ('\U00003015', '\U00003015'),
- ('\U00003017', '\U00003017'),
- ('\U00003019', '\U00003019'),
- ('\U0000301b', '\U0000301b'),
- ('\U0000301e', '\U0000301f'),
- ('\U0000fd3f', '\U0000fd3f'),
- ('\U0000fe18', '\U0000fe18'),
- ('\U0000fe36', '\U0000fe36'),
- ('\U0000fe38', '\U0000fe38'),
- ('\U0000fe3a', '\U0000fe3a'),
- ('\U0000fe3c', '\U0000fe3c'),
- ('\U0000fe3e', '\U0000fe3e'),
- ('\U0000fe40', '\U0000fe40'),
- ('\U0000fe42', '\U0000fe42'),
- ('\U0000fe44', '\U0000fe44'),
- ('\U0000fe48', '\U0000fe48'),
- ('\U0000fe5a', '\U0000fe5a'),
- ('\U0000fe5c', '\U0000fe5c'),
- ('\U0000fe5e', '\U0000fe5e'),
- ('\U0000ff09', '\U0000ff09'),
- ('\U0000ff3d', '\U0000ff3d'),
- ('\U0000ff5d', '\U0000ff5d'),
- ('\U0000ff60', '\U0000ff60'),
- ('\U0000ff63', '\U0000ff63')
- ]),
-("Pf", &[
- ('\U000000bb', '\U000000bb'),
- ('\U00002019', '\U00002019'),
- ('\U0000201d', '\U0000201d'),
- ('\U0000203a', '\U0000203a'),
- ('\U00002e03', '\U00002e03'),
- ('\U00002e05', '\U00002e05'),
- ('\U00002e0a', '\U00002e0a'),
- ('\U00002e0d', '\U00002e0d'),
- ('\U00002e1d', '\U00002e1d'),
- ('\U00002e21', '\U00002e21')
- ]),
-("Phags_Pa", &[
- ('\U0000a840', '\U0000a877')
- ]),
-("Phoenician", &[
- ('\U00010900', '\U0001091b'),
- ('\U0001091f', '\U0001091f')
- ]),
-("Pi", &[
- ('\U000000ab', '\U000000ab'),
- ('\U00002018', '\U00002018'),
- ('\U0000201b', '\U0000201c'),
- ('\U0000201f', '\U0000201f'),
- ('\U00002039', '\U00002039'),
- ('\U00002e02', '\U00002e02'),
- ('\U00002e04', '\U00002e04'),
- ('\U00002e09', '\U00002e09'),
- ('\U00002e0c', '\U00002e0c'),
- ('\U00002e1c', '\U00002e1c'),
- ('\U00002e20', '\U00002e20')
- ]),
-("Po", &[
- ('\U00000021', '\U00000023'),
- ('\U00000025', '\U00000027'),
- ('\U0000002a', '\U0000002a'),
- ('\U0000002c', '\U0000002c'),
- ('\U0000002e', '\U0000002f'),
- ('\U0000003a', '\U0000003b'),
- ('\U0000003f', '\U00000040'),
- ('\U0000005c', '\U0000005c'),
- ('\U000000a1', '\U000000a1'),
- ('\U000000a7', '\U000000a7'),
- ('\U000000b6', '\U000000b7'),
- ('\U000000bf', '\U000000bf'),
- ('\U0000037e', '\U0000037e'),
- ('\U00000387', '\U00000387'),
- ('\U0000055a', '\U0000055f'),
- ('\U00000589', '\U00000589'),
- ('\U000005c0', '\U000005c0'),
- ('\U000005c3', '\U000005c3'),
- ('\U000005c6', '\U000005c6'),
- ('\U000005f3', '\U000005f4'),
- ('\U00000609', '\U0000060a'),
- ('\U0000060c', '\U0000060d'),
- ('\U0000061b', '\U0000061b'),
- ('\U0000061e', '\U0000061f'),
- ('\U0000066a', '\U0000066d'),
- ('\U000006d4', '\U000006d4'),
- ('\U00000700', '\U0000070d'),
- ('\U000007f7', '\U000007f9'),
- ('\U00000830', '\U0000083e'),
- ('\U0000085e', '\U0000085e'),
- ('\U00000964', '\U00000965'),
- ('\U00000970', '\U00000970'),
- ('\U00000af0', '\U00000af0'),
- ('\U00000df4', '\U00000df4'),
- ('\U00000e4f', '\U00000e4f'),
- ('\U00000e5a', '\U00000e5b'),
- ('\U00000f04', '\U00000f12'),
- ('\U00000f14', '\U00000f14'),
- ('\U00000f85', '\U00000f85'),
- ('\U00000fd0', '\U00000fd4'),
- ('\U00000fd9', '\U00000fda'),
- ('\U0000104a', '\U0000104f'),
- ('\U000010fb', '\U000010fb'),
- ('\U00001360', '\U00001368'),
- ('\U0000166d', '\U0000166e'),
- ('\U000016eb', '\U000016ed'),
- ('\U00001735', '\U00001736'),
- ('\U000017d4', '\U000017d6'),
- ('\U000017d8', '\U000017da'),
- ('\U00001800', '\U00001805'),
- ('\U00001807', '\U0000180a'),
- ('\U00001944', '\U00001945'),
- ('\U00001a1e', '\U00001a1f'),
- ('\U00001aa0', '\U00001aa6'),
- ('\U00001aa8', '\U00001aad'),
- ('\U00001b5a', '\U00001b60'),
- ('\U00001bfc', '\U00001bff'),
- ('\U00001c3b', '\U00001c3f'),
- ('\U00001c7e', '\U00001c7f'),
- ('\U00001cc0', '\U00001cc7'),
- ('\U00001cd3', '\U00001cd3'),
- ('\U00002016', '\U00002017'),
- ('\U00002020', '\U00002027'),
- ('\U00002030', '\U00002038'),
- ('\U0000203b', '\U0000203e'),
- ('\U00002041', '\U00002043'),
- ('\U00002047', '\U00002051'),
- ('\U00002053', '\U00002053'),
- ('\U00002055', '\U0000205e'),
- ('\U00002cf9', '\U00002cfc'),
- ('\U00002cfe', '\U00002cff'),
- ('\U00002d70', '\U00002d70'),
- ('\U00002e00', '\U00002e01'),
- ('\U00002e06', '\U00002e08'),
- ('\U00002e0b', '\U00002e0b'),
- ('\U00002e0e', '\U00002e16'),
- ('\U00002e18', '\U00002e19'),
- ('\U00002e1b', '\U00002e1b'),
- ('\U00002e1e', '\U00002e1f'),
- ('\U00002e2a', '\U00002e2e'),
- ('\U00002e30', '\U00002e39'),
- ('\U00003001', '\U00003003'),
- ('\U0000303d', '\U0000303d'),
- ('\U000030fb', '\U000030fb'),
- ('\U0000a4fe', '\U0000a4ff'),
- ('\U0000a60d', '\U0000a60f'),
- ('\U0000a673', '\U0000a673'),
- ('\U0000a67e', '\U0000a67e'),
- ('\U0000a6f2', '\U0000a6f7'),
- ('\U0000a874', '\U0000a877'),
- ('\U0000a8ce', '\U0000a8cf'),
- ('\U0000a8f8', '\U0000a8fa'),
- ('\U0000a92e', '\U0000a92f'),
- ('\U0000a95f', '\U0000a95f'),
- ('\U0000a9c1', '\U0000a9cd'),
- ('\U0000a9de', '\U0000a9df'),
- ('\U0000aa5c', '\U0000aa5f'),
- ('\U0000aade', '\U0000aadf'),
- ('\U0000aaf0', '\U0000aaf1'),
- ('\U0000abeb', '\U0000abeb'),
- ('\U0000fe10', '\U0000fe16'),
- ('\U0000fe19', '\U0000fe19'),
- ('\U0000fe30', '\U0000fe30'),
- ('\U0000fe45', '\U0000fe46'),
- ('\U0000fe49', '\U0000fe4c'),
- ('\U0000fe50', '\U0000fe52'),
- ('\U0000fe54', '\U0000fe57'),
- ('\U0000fe5f', '\U0000fe61'),
- ('\U0000fe68', '\U0000fe68'),
- ('\U0000fe6a', '\U0000fe6b'),
- ('\U0000ff01', '\U0000ff03'),
- ('\U0000ff05', '\U0000ff07'),
- ('\U0000ff0a', '\U0000ff0a'),
- ('\U0000ff0c', '\U0000ff0c'),
- ('\U0000ff0e', '\U0000ff0f'),
- ('\U0000ff1a', '\U0000ff1b'),
- ('\U0000ff1f', '\U0000ff20'),
- ('\U0000ff3c', '\U0000ff3c'),
- ('\U0000ff61', '\U0000ff61'),
- ('\U0000ff64', '\U0000ff65'),
- ('\U00010100', '\U00010102'),
- ('\U0001039f', '\U0001039f'),
- ('\U000103d0', '\U000103d0'),
- ('\U00010857', '\U00010857'),
- ('\U0001091f', '\U0001091f'),
- ('\U0001093f', '\U0001093f'),
- ('\U00010a50', '\U00010a58'),
- ('\U00010a7f', '\U00010a7f'),
- ('\U00010b39', '\U00010b3f'),
- ('\U00011047', '\U0001104d'),
- ('\U000110bb', '\U000110bc'),
- ('\U000110be', '\U000110c1'),
- ('\U00011140', '\U00011143'),
- ('\U000111c5', '\U000111c8'),
- ('\U00012470', '\U00012473')
- ]),
-("Ps", &[
- ('\U00000028', '\U00000028'),
- ('\U0000005b', '\U0000005b'),
- ('\U0000007b', '\U0000007b'),
- ('\U00000f3a', '\U00000f3a'),
- ('\U00000f3c', '\U00000f3c'),
- ('\U0000169b', '\U0000169b'),
- ('\U0000201a', '\U0000201a'),
- ('\U0000201e', '\U0000201e'),
- ('\U00002045', '\U00002045'),
- ('\U0000207d', '\U0000207d'),
- ('\U0000208d', '\U0000208d'),
- ('\U00002308', '\U00002308'),
- ('\U0000230a', '\U0000230a'),
- ('\U00002329', '\U00002329'),
- ('\U00002768', '\U00002768'),
- ('\U0000276a', '\U0000276a'),
- ('\U0000276c', '\U0000276c'),
- ('\U0000276e', '\U0000276e'),
- ('\U00002770', '\U00002770'),
- ('\U00002772', '\U00002772'),
- ('\U00002774', '\U00002774'),
- ('\U000027c5', '\U000027c5'),
- ('\U000027e6', '\U000027e6'),
- ('\U000027e8', '\U000027e8'),
- ('\U000027ea', '\U000027ea'),
- ('\U000027ec', '\U000027ec'),
- ('\U000027ee', '\U000027ee'),
- ('\U00002983', '\U00002983'),
- ('\U00002985', '\U00002985'),
- ('\U00002987', '\U00002987'),
- ('\U00002989', '\U00002989'),
- ('\U0000298b', '\U0000298b'),
- ('\U0000298d', '\U0000298d'),
- ('\U0000298f', '\U0000298f'),
- ('\U00002991', '\U00002991'),
- ('\U00002993', '\U00002993'),
- ('\U00002995', '\U00002995'),
- ('\U00002997', '\U00002997'),
- ('\U000029d8', '\U000029d8'),
- ('\U000029da', '\U000029da'),
- ('\U000029fc', '\U000029fc'),
- ('\U00002e22', '\U00002e22'),
- ('\U00002e24', '\U00002e24'),
- ('\U00002e26', '\U00002e26'),
- ('\U00002e28', '\U00002e28'),
- ('\U00003008', '\U00003008'),
- ('\U0000300a', '\U0000300a'),
- ('\U0000300c', '\U0000300c'),
- ('\U0000300e', '\U0000300e'),
- ('\U00003010', '\U00003010'),
- ('\U00003014', '\U00003014'),
- ('\U00003016', '\U00003016'),
- ('\U00003018', '\U00003018'),
- ('\U0000301a', '\U0000301a'),
- ('\U0000301d', '\U0000301d'),
- ('\U0000fd3e', '\U0000fd3e'),
- ('\U0000fe17', '\U0000fe17'),
- ('\U0000fe35', '\U0000fe35'),
- ('\U0000fe37', '\U0000fe37'),
- ('\U0000fe39', '\U0000fe39'),
- ('\U0000fe3b', '\U0000fe3b'),
- ('\U0000fe3d', '\U0000fe3d'),
- ('\U0000fe3f', '\U0000fe3f'),
- ('\U0000fe41', '\U0000fe41'),
- ('\U0000fe43', '\U0000fe43'),
- ('\U0000fe47', '\U0000fe47'),
- ('\U0000fe59', '\U0000fe59'),
- ('\U0000fe5b', '\U0000fe5b'),
- ('\U0000fe5d', '\U0000fe5d'),
- ('\U0000ff08', '\U0000ff08'),
- ('\U0000ff3b', '\U0000ff3b'),
- ('\U0000ff5b', '\U0000ff5b'),
- ('\U0000ff5f', '\U0000ff5f'),
- ('\U0000ff62', '\U0000ff62')
- ]),
-("Rejang", &[
- ('\U0000a930', '\U0000a953'),
- ('\U0000a95f', '\U0000a95f')
- ]),
-("Runic", &[
- ('\U000016a0', '\U000016ea'),
- ('\U000016ee', '\U000016f0')
- ]),
-("S", &[
- ('\U00000024', '\U00000024'),
- ('\U0000002b', '\U0000002b'),
- ('\U0000003c', '\U0000003e'),
- ('\U0000005e', '\U0000005e'),
- ('\U00000060', '\U00000060'),
- ('\U0000007c', '\U0000007c'),
- ('\U0000007e', '\U0000007e'),
- ('\U000000a2', '\U000000a6'),
- ('\U000000a8', '\U000000a9'),
- ('\U000000ac', '\U000000ac'),
- ('\U000000ae', '\U000000b1'),
- ('\U000000b4', '\U000000b4'),
- ('\U000000b8', '\U000000b8'),
- ('\U000000d7', '\U000000d7'),
- ('\U000000f7', '\U000000f7'),
- ('\U000002c2', '\U000002c5'),
- ('\U000002d2', '\U000002df'),
- ('\U000002e5', '\U000002eb'),
- ('\U000002ed', '\U000002ed'),
- ('\U000002ef', '\U000002ff'),
- ('\U00000375', '\U00000375'),
- ('\U00000384', '\U00000385'),
- ('\U000003f6', '\U000003f6'),
- ('\U00000482', '\U00000482'),
- ('\U0000058f', '\U0000058f'),
- ('\U00000606', '\U00000608'),
- ('\U0000060b', '\U0000060b'),
- ('\U0000060e', '\U0000060f'),
- ('\U000006de', '\U000006de'),
- ('\U000006e9', '\U000006e9'),
- ('\U000006fd', '\U000006fe'),
- ('\U000007f6', '\U000007f6'),
- ('\U000009f2', '\U000009f3'),
- ('\U000009fa', '\U000009fb'),
- ('\U00000af1', '\U00000af1'),
- ('\U00000b70', '\U00000b70'),
- ('\U00000bf3', '\U00000bfa'),
- ('\U00000c7f', '\U00000c7f'),
- ('\U00000d79', '\U00000d79'),
- ('\U00000e3f', '\U00000e3f'),
- ('\U00000f01', '\U00000f03'),
- ('\U00000f13', '\U00000f13'),
- ('\U00000f15', '\U00000f17'),
- ('\U00000f1a', '\U00000f1f'),
- ('\U00000f34', '\U00000f34'),
- ('\U00000f36', '\U00000f36'),
- ('\U00000f38', '\U00000f38'),
- ('\U00000fbe', '\U00000fc5'),
- ('\U00000fc7', '\U00000fcc'),
- ('\U00000fce', '\U00000fcf'),
- ('\U00000fd5', '\U00000fd8'),
- ('\U0000109e', '\U0000109f'),
- ('\U00001390', '\U00001399'),
- ('\U000017db', '\U000017db'),
- ('\U00001940', '\U00001940'),
- ('\U000019de', '\U000019ff'),
- ('\U00001b61', '\U00001b6a'),
- ('\U00001b74', '\U00001b7c'),
- ('\U00001fbd', '\U00001fbd'),
- ('\U00001fbf', '\U00001fc1'),
- ('\U00001fcd', '\U00001fcf'),
- ('\U00001fdd', '\U00001fdf'),
- ('\U00001fed', '\U00001fef'),
- ('\U00001ffd', '\U00001ffe'),
- ('\U00002044', '\U00002044'),
- ('\U00002052', '\U00002052'),
- ('\U0000207a', '\U0000207c'),
- ('\U0000208a', '\U0000208c'),
- ('\U000020a0', '\U000020ba'),
- ('\U00002100', '\U00002101'),
- ('\U00002103', '\U00002106'),
- ('\U00002108', '\U00002109'),
- ('\U00002114', '\U00002114'),
- ('\U00002116', '\U00002118'),
- ('\U0000211e', '\U00002123'),
- ('\U00002125', '\U00002125'),
- ('\U00002127', '\U00002127'),
- ('\U00002129', '\U00002129'),
- ('\U0000212e', '\U0000212e'),
- ('\U0000213a', '\U0000213b'),
- ('\U00002140', '\U00002144'),
- ('\U0000214a', '\U0000214d'),
- ('\U0000214f', '\U0000214f'),
- ('\U00002190', '\U00002307'),
- ('\U0000230c', '\U00002328'),
- ('\U0000232b', '\U000023f3'),
- ('\U00002400', '\U00002426'),
- ('\U00002440', '\U0000244a'),
- ('\U0000249c', '\U000024e9'),
- ('\U00002500', '\U000026ff'),
- ('\U00002701', '\U00002767'),
- ('\U00002794', '\U000027c4'),
- ('\U000027c7', '\U000027e5'),
- ('\U000027f0', '\U00002982'),
- ('\U00002999', '\U000029d7'),
- ('\U000029dc', '\U000029fb'),
- ('\U000029fe', '\U00002b4c'),
- ('\U00002b50', '\U00002b59'),
- ('\U00002ce5', '\U00002cea'),
- ('\U00002e80', '\U00002e99'),
- ('\U00002e9b', '\U00002ef3'),
- ('\U00002f00', '\U00002fd5'),
- ('\U00002ff0', '\U00002ffb'),
- ('\U00003004', '\U00003004'),
- ('\U00003012', '\U00003013'),
- ('\U00003020', '\U00003020'),
- ('\U00003036', '\U00003037'),
- ('\U0000303e', '\U0000303f'),
- ('\U0000309b', '\U0000309c'),
- ('\U00003190', '\U00003191'),
- ('\U00003196', '\U0000319f'),
- ('\U000031c0', '\U000031e3'),
- ('\U00003200', '\U0000321e'),
- ('\U0000322a', '\U00003247'),
- ('\U00003250', '\U00003250'),
- ('\U00003260', '\U0000327f'),
- ('\U0000328a', '\U000032b0'),
- ('\U000032c0', '\U000032fe'),
- ('\U00003300', '\U000033ff'),
- ('\U00004dc0', '\U00004dff'),
- ('\U0000a490', '\U0000a4c6'),
- ('\U0000a700', '\U0000a716'),
- ('\U0000a720', '\U0000a721'),
- ('\U0000a789', '\U0000a78a'),
- ('\U0000a828', '\U0000a82b'),
- ('\U0000a836', '\U0000a839'),
- ('\U0000aa77', '\U0000aa79'),
- ('\U0000fb29', '\U0000fb29'),
- ('\U0000fbb2', '\U0000fbc1'),
- ('\U0000fdfc', '\U0000fdfd'),
- ('\U0000fe62', '\U0000fe62'),
- ('\U0000fe64', '\U0000fe66'),
- ('\U0000fe69', '\U0000fe69'),
- ('\U0000ff04', '\U0000ff04'),
- ('\U0000ff0b', '\U0000ff0b'),
- ('\U0000ff1c', '\U0000ff1e'),
- ('\U0000ff3e', '\U0000ff3e'),
- ('\U0000ff40', '\U0000ff40'),
- ('\U0000ff5c', '\U0000ff5c'),
- ('\U0000ff5e', '\U0000ff5e'),
- ('\U0000ffe0', '\U0000ffe6'),
- ('\U0000ffe8', '\U0000ffee'),
- ('\U0000fffc', '\U0000fffd'),
- ('\U00010137', '\U0001013f'),
- ('\U00010179', '\U00010189'),
- ('\U00010190', '\U0001019b'),
- ('\U000101d0', '\U000101fc'),
- ('\U0001d000', '\U0001d0f5'),
- ('\U0001d100', '\U0001d126'),
- ('\U0001d129', '\U0001d164'),
- ('\U0001d16a', '\U0001d16c'),
- ('\U0001d183', '\U0001d184'),
- ('\U0001d18c', '\U0001d1a9'),
- ('\U0001d1ae', '\U0001d1dd'),
- ('\U0001d200', '\U0001d241'),
- ('\U0001d245', '\U0001d245'),
- ('\U0001d300', '\U0001d356'),
- ('\U0001d6c1', '\U0001d6c1'),
- ('\U0001d6db', '\U0001d6db'),
- ('\U0001d6fb', '\U0001d6fb'),
- ('\U0001d715', '\U0001d715'),
- ('\U0001d735', '\U0001d735'),
- ('\U0001d74f', '\U0001d74f'),
- ('\U0001d76f', '\U0001d76f'),
- ('\U0001d789', '\U0001d789'),
- ('\U0001d7a9', '\U0001d7a9'),
- ('\U0001d7c3', '\U0001d7c3'),
- ('\U0001eef0', '\U0001eef1'),
- ('\U0001f000', '\U0001f02b'),
- ('\U0001f030', '\U0001f093'),
- ('\U0001f0a0', '\U0001f0ae'),
- ('\U0001f0b1', '\U0001f0be'),
- ('\U0001f0c1', '\U0001f0cf'),
- ('\U0001f0d1', '\U0001f0df'),
- ('\U0001f110', '\U0001f12e'),
- ('\U0001f130', '\U0001f16b'),
- ('\U0001f170', '\U0001f19a'),
- ('\U0001f1e6', '\U0001f202'),
- ('\U0001f210', '\U0001f23a'),
- ('\U0001f240', '\U0001f248'),
- ('\U0001f250', '\U0001f251'),
- ('\U0001f300', '\U0001f320'),
- ('\U0001f330', '\U0001f335'),
- ('\U0001f337', '\U0001f37c'),
- ('\U0001f380', '\U0001f393'),
- ('\U0001f3a0', '\U0001f3c4'),
- ('\U0001f3c6', '\U0001f3ca'),
- ('\U0001f3e0', '\U0001f3f0'),
- ('\U0001f400', '\U0001f43e'),
- ('\U0001f440', '\U0001f440'),
- ('\U0001f442', '\U0001f4f7'),
- ('\U0001f4f9', '\U0001f4fc'),
- ('\U0001f500', '\U0001f53d'),
- ('\U0001f540', '\U0001f543'),
- ('\U0001f550', '\U0001f567'),
- ('\U0001f5fb', '\U0001f640'),
- ('\U0001f645', '\U0001f64f'),
- ('\U0001f680', '\U0001f6c5'),
- ('\U0001f700', '\U0001f773')
- ]),
-("Samaritan", &[
- ('\U00000800', '\U0000082d'),
- ('\U00000830', '\U0000083e')
- ]),
-("Saurashtra", &[
- ('\U0000a880', '\U0000a8c4'),
- ('\U0000a8ce', '\U0000a8d9')
- ]),
-("Sc", &[
- ('\U00000024', '\U00000024'),
- ('\U000000a2', '\U000000a5'),
- ('\U0000058f', '\U0000058f'),
- ('\U0000060b', '\U0000060b'),
- ('\U000009f2', '\U000009f3'),
- ('\U000009fb', '\U000009fb'),
- ('\U00000af1', '\U00000af1'),
- ('\U00000bf9', '\U00000bf9'),
- ('\U00000e3f', '\U00000e3f'),
- ('\U000017db', '\U000017db'),
- ('\U000020a0', '\U000020ba'),
- ('\U0000a838', '\U0000a838'),
- ('\U0000fdfc', '\U0000fdfc'),
- ('\U0000fe69', '\U0000fe69'),
- ('\U0000ff04', '\U0000ff04'),
- ('\U0000ffe0', '\U0000ffe1'),
- ('\U0000ffe5', '\U0000ffe6')
- ]),
-("Sharada", &[
- ('\U00011180', '\U000111c8'),
- ('\U000111d0', '\U000111d9')
- ]),
-("Shavian", &[
- ('\U00010450', '\U0001047f')
- ]),
-("Sinhala", &[
- ('\U00000d82', '\U00000d83'),
- ('\U00000d85', '\U00000d96'),
- ('\U00000d9a', '\U00000db1'),
- ('\U00000db3', '\U00000dbb'),
- ('\U00000dbd', '\U00000dbd'),
- ('\U00000dc0', '\U00000dc6'),
- ('\U00000dca', '\U00000dca'),
- ('\U00000dcf', '\U00000dd4'),
- ('\U00000dd6', '\U00000dd6'),
- ('\U00000dd8', '\U00000ddf'),
- ('\U00000df2', '\U00000df4')
- ]),
-("Sk", &[
- ('\U0000005e', '\U0000005e'),
- ('\U00000060', '\U00000060'),
- ('\U000000a8', '\U000000a8'),
- ('\U000000af', '\U000000af'),
- ('\U000000b4', '\U000000b4'),
- ('\U000000b8', '\U000000b8'),
- ('\U000002c2', '\U000002c5'),
- ('\U000002d2', '\U000002df'),
- ('\U000002e5', '\U000002eb'),
- ('\U000002ed', '\U000002ed'),
- ('\U000002ef', '\U000002ff'),
- ('\U00000375', '\U00000375'),
- ('\U00000384', '\U00000385'),
- ('\U00001fbd', '\U00001fbd'),
- ('\U00001fbf', '\U00001fc1'),
- ('\U00001fcd', '\U00001fcf'),
- ('\U00001fdd', '\U00001fdf'),
- ('\U00001fed', '\U00001fef'),
- ('\U00001ffd', '\U00001ffe'),
- ('\U0000309b', '\U0000309c'),
- ('\U0000a700', '\U0000a716'),
- ('\U0000a720', '\U0000a721'),
- ('\U0000a789', '\U0000a78a'),
- ('\U0000fbb2', '\U0000fbc1'),
- ('\U0000ff3e', '\U0000ff3e'),
- ('\U0000ff40', '\U0000ff40'),
- ('\U0000ffe3', '\U0000ffe3')
- ]),
-("Sm", &[
- ('\U0000002b', '\U0000002b'),
- ('\U0000003c', '\U0000003e'),
- ('\U0000007c', '\U0000007c'),
- ('\U0000007e', '\U0000007e'),
- ('\U000000ac', '\U000000ac'),
- ('\U000000b1', '\U000000b1'),
- ('\U000000d7', '\U000000d7'),
- ('\U000000f7', '\U000000f7'),
- ('\U000003f6', '\U000003f6'),
- ('\U00000606', '\U00000608'),
- ('\U00002044', '\U00002044'),
- ('\U00002052', '\U00002052'),
- ('\U0000207a', '\U0000207c'),
- ('\U0000208a', '\U0000208c'),
- ('\U00002118', '\U00002118'),
- ('\U00002140', '\U00002144'),
- ('\U0000214b', '\U0000214b'),
- ('\U00002190', '\U00002194'),
- ('\U0000219a', '\U0000219b'),
- ('\U000021a0', '\U000021a0'),
- ('\U000021a3', '\U000021a3'),
- ('\U000021a6', '\U000021a6'),
- ('\U000021ae', '\U000021ae'),
- ('\U000021ce', '\U000021cf'),
- ('\U000021d2', '\U000021d2'),
- ('\U000021d4', '\U000021d4'),
- ('\U000021f4', '\U000022ff'),
- ('\U00002320', '\U00002321'),
- ('\U0000237c', '\U0000237c'),
- ('\U0000239b', '\U000023b3'),
- ('\U000023dc', '\U000023e1'),
- ('\U000025b7', '\U000025b7'),
- ('\U000025c1', '\U000025c1'),
- ('\U000025f8', '\U000025ff'),
- ('\U0000266f', '\U0000266f'),
- ('\U000027c0', '\U000027c4'),
- ('\U000027c7', '\U000027e5'),
- ('\U000027f0', '\U000027ff'),
- ('\U00002900', '\U00002982'),
- ('\U00002999', '\U000029d7'),
- ('\U000029dc', '\U000029fb'),
- ('\U000029fe', '\U00002aff'),
- ('\U00002b30', '\U00002b44'),
- ('\U00002b47', '\U00002b4c'),
- ('\U0000fb29', '\U0000fb29'),
- ('\U0000fe62', '\U0000fe62'),
- ('\U0000fe64', '\U0000fe66'),
- ('\U0000ff0b', '\U0000ff0b'),
- ('\U0000ff1c', '\U0000ff1e'),
- ('\U0000ff5c', '\U0000ff5c'),
- ('\U0000ff5e', '\U0000ff5e'),
- ('\U0000ffe2', '\U0000ffe2'),
- ('\U0000ffe9', '\U0000ffec'),
- ('\U0001d6c1', '\U0001d6c1'),
- ('\U0001d6db', '\U0001d6db'),
- ('\U0001d6fb', '\U0001d6fb'),
- ('\U0001d715', '\U0001d715'),
- ('\U0001d735', '\U0001d735'),
- ('\U0001d74f', '\U0001d74f'),
- ('\U0001d76f', '\U0001d76f'),
- ('\U0001d789', '\U0001d789'),
- ('\U0001d7a9', '\U0001d7a9'),
- ('\U0001d7c3', '\U0001d7c3'),
- ('\U0001eef0', '\U0001eef1')
- ]),
-("So", &[
- ('\U000000a6', '\U000000a6'),
- ('\U000000a9', '\U000000a9'),
- ('\U000000ae', '\U000000ae'),
- ('\U000000b0', '\U000000b0'),
- ('\U00000482', '\U00000482'),
- ('\U0000060e', '\U0000060f'),
- ('\U000006de', '\U000006de'),
- ('\U000006e9', '\U000006e9'),
- ('\U000006fd', '\U000006fe'),
- ('\U000007f6', '\U000007f6'),
- ('\U000009fa', '\U000009fa'),
- ('\U00000b70', '\U00000b70'),
- ('\U00000bf3', '\U00000bf8'),
- ('\U00000bfa', '\U00000bfa'),
- ('\U00000c7f', '\U00000c7f'),
- ('\U00000d79', '\U00000d79'),
- ('\U00000f01', '\U00000f03'),
- ('\U00000f13', '\U00000f13'),
- ('\U00000f15', '\U00000f17'),
- ('\U00000f1a', '\U00000f1f'),
- ('\U00000f34', '\U00000f34'),
- ('\U00000f36', '\U00000f36'),
- ('\U00000f38', '\U00000f38'),
- ('\U00000fbe', '\U00000fc5'),
- ('\U00000fc7', '\U00000fcc'),
- ('\U00000fce', '\U00000fcf'),
- ('\U00000fd5', '\U00000fd8'),
- ('\U0000109e', '\U0000109f'),
- ('\U00001390', '\U00001399'),
- ('\U00001940', '\U00001940'),
- ('\U000019de', '\U000019ff'),
- ('\U00001b61', '\U00001b6a'),
- ('\U00001b74', '\U00001b7c'),
- ('\U00002100', '\U00002101'),
- ('\U00002103', '\U00002106'),
- ('\U00002108', '\U00002109'),
- ('\U00002114', '\U00002114'),
- ('\U00002116', '\U00002117'),
- ('\U0000211e', '\U00002123'),
- ('\U00002125', '\U00002125'),
- ('\U00002127', '\U00002127'),
- ('\U00002129', '\U00002129'),
- ('\U0000212e', '\U0000212e'),
- ('\U0000213a', '\U0000213b'),
- ('\U0000214a', '\U0000214a'),
- ('\U0000214c', '\U0000214d'),
- ('\U0000214f', '\U0000214f'),
- ('\U00002195', '\U00002199'),
- ('\U0000219c', '\U0000219f'),
- ('\U000021a1', '\U000021a2'),
- ('\U000021a4', '\U000021a5'),
- ('\U000021a7', '\U000021ad'),
- ('\U000021af', '\U000021cd'),
- ('\U000021d0', '\U000021d1'),
- ('\U000021d3', '\U000021d3'),
- ('\U000021d5', '\U000021f3'),
- ('\U00002300', '\U00002307'),
- ('\U0000230c', '\U0000231f'),
- ('\U00002322', '\U00002328'),
- ('\U0000232b', '\U0000237b'),
- ('\U0000237d', '\U0000239a'),
- ('\U000023b4', '\U000023db'),
- ('\U000023e2', '\U000023f3'),
- ('\U00002400', '\U00002426'),
- ('\U00002440', '\U0000244a'),
- ('\U0000249c', '\U000024e9'),
- ('\U00002500', '\U000025b6'),
- ('\U000025b8', '\U000025c0'),
- ('\U000025c2', '\U000025f7'),
- ('\U00002600', '\U0000266e'),
- ('\U00002670', '\U000026ff'),
- ('\U00002701', '\U00002767'),
- ('\U00002794', '\U000027bf'),
- ('\U00002800', '\U000028ff'),
- ('\U00002b00', '\U00002b2f'),
- ('\U00002b45', '\U00002b46'),
- ('\U00002b50', '\U00002b59'),
- ('\U00002ce5', '\U00002cea'),
- ('\U00002e80', '\U00002e99'),
- ('\U00002e9b', '\U00002ef3'),
- ('\U00002f00', '\U00002fd5'),
- ('\U00002ff0', '\U00002ffb'),
- ('\U00003004', '\U00003004'),
- ('\U00003012', '\U00003013'),
- ('\U00003020', '\U00003020'),
- ('\U00003036', '\U00003037'),
- ('\U0000303e', '\U0000303f'),
- ('\U00003190', '\U00003191'),
- ('\U00003196', '\U0000319f'),
- ('\U000031c0', '\U000031e3'),
- ('\U00003200', '\U0000321e'),
- ('\U0000322a', '\U00003247'),
- ('\U00003250', '\U00003250'),
- ('\U00003260', '\U0000327f'),
- ('\U0000328a', '\U000032b0'),
- ('\U000032c0', '\U000032fe'),
- ('\U00003300', '\U000033ff'),
- ('\U00004dc0', '\U00004dff'),
- ('\U0000a490', '\U0000a4c6'),
- ('\U0000a828', '\U0000a82b'),
- ('\U0000a836', '\U0000a837'),
- ('\U0000a839', '\U0000a839'),
- ('\U0000aa77', '\U0000aa79'),
- ('\U0000fdfd', '\U0000fdfd'),
- ('\U0000ffe4', '\U0000ffe4'),
- ('\U0000ffe8', '\U0000ffe8'),
- ('\U0000ffed', '\U0000ffee'),
- ('\U0000fffc', '\U0000fffd'),
- ('\U00010137', '\U0001013f'),
- ('\U00010179', '\U00010189'),
- ('\U00010190', '\U0001019b'),
- ('\U000101d0', '\U000101fc'),
- ('\U0001d000', '\U0001d0f5'),
- ('\U0001d100', '\U0001d126'),
- ('\U0001d129', '\U0001d164'),
- ('\U0001d16a', '\U0001d16c'),
- ('\U0001d183', '\U0001d184'),
- ('\U0001d18c', '\U0001d1a9'),
- ('\U0001d1ae', '\U0001d1dd'),
- ('\U0001d200', '\U0001d241'),
- ('\U0001d245', '\U0001d245'),
- ('\U0001d300', '\U0001d356'),
- ('\U0001f000', '\U0001f02b'),
- ('\U0001f030', '\U0001f093'),
- ('\U0001f0a0', '\U0001f0ae'),
- ('\U0001f0b1', '\U0001f0be'),
- ('\U0001f0c1', '\U0001f0cf'),
- ('\U0001f0d1', '\U0001f0df'),
- ('\U0001f110', '\U0001f12e'),
- ('\U0001f130', '\U0001f16b'),
- ('\U0001f170', '\U0001f19a'),
- ('\U0001f1e6', '\U0001f202'),
- ('\U0001f210', '\U0001f23a'),
- ('\U0001f240', '\U0001f248'),
- ('\U0001f250', '\U0001f251'),
- ('\U0001f300', '\U0001f320'),
- ('\U0001f330', '\U0001f335'),
- ('\U0001f337', '\U0001f37c'),
- ('\U0001f380', '\U0001f393'),
- ('\U0001f3a0', '\U0001f3c4'),
- ('\U0001f3c6', '\U0001f3ca'),
- ('\U0001f3e0', '\U0001f3f0'),
- ('\U0001f400', '\U0001f43e'),
- ('\U0001f440', '\U0001f440'),
- ('\U0001f442', '\U0001f4f7'),
- ('\U0001f4f9', '\U0001f4fc'),
- ('\U0001f500', '\U0001f53d'),
- ('\U0001f540', '\U0001f543'),
- ('\U0001f550', '\U0001f567'),
- ('\U0001f5fb', '\U0001f640'),
- ('\U0001f645', '\U0001f64f'),
- ('\U0001f680', '\U0001f6c5'),
- ('\U0001f700', '\U0001f773')
- ]),
-("Sora_Sompeng", &[
- ('\U000110d0', '\U000110e8'),
- ('\U000110f0', '\U000110f9')
- ]),
-("Sundanese", &[
- ('\U00001b80', '\U00001bbf'),
- ('\U00001cc0', '\U00001cc7')
- ]),
-("Syloti_Nagri", &[
- ('\U0000a800', '\U0000a82b')
- ]),
-("Syriac", &[
- ('\U00000700', '\U0000070d'),
- ('\U0000070f', '\U0000074a'),
- ('\U0000074d', '\U0000074f')
- ]),
-("Tagalog", &[
- ('\U00001700', '\U0000170c'),
- ('\U0000170e', '\U00001714')
- ]),
-("Tagbanwa", &[
- ('\U00001760', '\U0000176c'),
- ('\U0000176e', '\U00001770'),
- ('\U00001772', '\U00001773')
- ]),
-("Tai_Le", &[
- ('\U00001950', '\U0000196d'),
- ('\U00001970', '\U00001974')
- ]),
-("Tai_Tham", &[
- ('\U00001a20', '\U00001a5e'),
- ('\U00001a60', '\U00001a7c'),
- ('\U00001a7f', '\U00001a89'),
- ('\U00001a90', '\U00001a99'),
- ('\U00001aa0', '\U00001aad')
- ]),
-("Tai_Viet", &[
- ('\U0000aa80', '\U0000aac2'),
- ('\U0000aadb', '\U0000aadf')
- ]),
-("Takri", &[
- ('\U00011680', '\U000116b7'),
- ('\U000116c0', '\U000116c9')
- ]),
-("Tamil", &[
- ('\U00000b82', '\U00000b83'),
- ('\U00000b85', '\U00000b8a'),
- ('\U00000b8e', '\U00000b90'),
- ('\U00000b92', '\U00000b95'),
- ('\U00000b99', '\U00000b9a'),
- ('\U00000b9c', '\U00000b9c'),
- ('\U00000b9e', '\U00000b9f'),
- ('\U00000ba3', '\U00000ba4'),
- ('\U00000ba8', '\U00000baa'),
- ('\U00000bae', '\U00000bb9'),
- ('\U00000bbe', '\U00000bc2'),
- ('\U00000bc6', '\U00000bc8'),
- ('\U00000bca', '\U00000bcd'),
- ('\U00000bd0', '\U00000bd0'),
- ('\U00000bd7', '\U00000bd7'),
- ('\U00000be6', '\U00000bfa')
- ]),
-("Telugu", &[
- ('\U00000c01', '\U00000c03'),
- ('\U00000c05', '\U00000c0c'),
- ('\U00000c0e', '\U00000c10'),
- ('\U00000c12', '\U00000c28'),
- ('\U00000c2a', '\U00000c33'),
- ('\U00000c35', '\U00000c39'),
- ('\U00000c3d', '\U00000c44'),
- ('\U00000c46', '\U00000c48'),
- ('\U00000c4a', '\U00000c4d'),
- ('\U00000c55', '\U00000c56'),
- ('\U00000c58', '\U00000c59'),
- ('\U00000c60', '\U00000c63'),
- ('\U00000c66', '\U00000c6f'),
- ('\U00000c78', '\U00000c7f')
- ]),
-("Thaana", &[
- ('\U00000780', '\U000007b1')
- ]),
-("Thai", &[
- ('\U00000e01', '\U00000e3a'),
- ('\U00000e40', '\U00000e5b')
- ]),
-("Tibetan", &[
- ('\U00000f00', '\U00000f47'),
- ('\U00000f49', '\U00000f6c'),
- ('\U00000f71', '\U00000f97'),
- ('\U00000f99', '\U00000fbc'),
- ('\U00000fbe', '\U00000fcc'),
- ('\U00000fce', '\U00000fd4'),
- ('\U00000fd9', '\U00000fda')
- ]),
-("Tifinagh", &[
- ('\U00002d30', '\U00002d67'),
- ('\U00002d6f', '\U00002d70'),
- ('\U00002d7f', '\U00002d7f')
- ]),
-("Ugaritic", &[
- ('\U00010380', '\U0001039d'),
- ('\U0001039f', '\U0001039f')
- ]),
-("Vai", &[
- ('\U0000a500', '\U0000a62b')
- ]),
-("Yi", &[
- ('\U0000a000', '\U0000a48c'),
- ('\U0000a490', '\U0000a4c6')
- ]),
-("Z", &[
- ('\U00000020', '\U00000020'),
- ('\U000000a0', '\U000000a0'),
- ('\U00001680', '\U00001680'),
- ('\U00002000', '\U0000200a'),
- ('\U00002028', '\U00002029'),
- ('\U0000202f', '\U0000202f'),
- ('\U0000205f', '\U0000205f'),
- ('\U00003000', '\U00003000')
- ]),
-("Zl", &[
- ('\U00002028', '\U00002028')
- ]),
-("Zp", &[
- ('\U00002029', '\U00002029')
- ]),
-("Zs", &[
- ('\U00000020', '\U00000020'),
- ('\U000000a0', '\U000000a0'),
- ('\U00001680', '\U00001680'),
- ('\U00002000', '\U0000200a'),
- ('\U0000202f', '\U0000202f'),
- ('\U0000205f', '\U0000205f'),
- ('\U00003000', '\U00003000')
- ]),
-
-];
-
-pub static PERLD: Class = &[
- ('\U00000030', '\U00000039'),
- ('\U00000660', '\U00000669'),
- ('\U000006f0', '\U000006f9'),
- ('\U000007c0', '\U000007c9'),
- ('\U00000966', '\U0000096f'),
- ('\U000009e6', '\U000009ef'),
- ('\U00000a66', '\U00000a6f'),
- ('\U00000ae6', '\U00000aef'),
- ('\U00000b66', '\U00000b6f'),
- ('\U00000be6', '\U00000bef'),
- ('\U00000c66', '\U00000c6f'),
- ('\U00000ce6', '\U00000cef'),
- ('\U00000d66', '\U00000d6f'),
- ('\U00000e50', '\U00000e59'),
- ('\U00000ed0', '\U00000ed9'),
- ('\U00000f20', '\U00000f29'),
- ('\U00001040', '\U00001049'),
- ('\U00001090', '\U00001099'),
- ('\U000017e0', '\U000017e9'),
- ('\U00001810', '\U00001819'),
- ('\U00001946', '\U0000194f'),
- ('\U000019d0', '\U000019d9'),
- ('\U00001a80', '\U00001a89'),
- ('\U00001a90', '\U00001a99'),
- ('\U00001b50', '\U00001b59'),
- ('\U00001bb0', '\U00001bb9'),
- ('\U00001c40', '\U00001c49'),
- ('\U00001c50', '\U00001c59'),
- ('\U0000a620', '\U0000a629'),
- ('\U0000a8d0', '\U0000a8d9'),
- ('\U0000a900', '\U0000a909'),
- ('\U0000a9d0', '\U0000a9d9'),
- ('\U0000aa50', '\U0000aa59'),
- ('\U0000abf0', '\U0000abf9'),
- ('\U0000ff10', '\U0000ff19'),
- ('\U000104a0', '\U000104a9'),
- ('\U00011066', '\U0001106f'),
- ('\U000110f0', '\U000110f9'),
- ('\U00011136', '\U0001113f'),
- ('\U000111d0', '\U000111d9'),
- ('\U000116c0', '\U000116c9'),
- ('\U0001d7ce', '\U0001d7ff')
-];
-
-pub static PERLS: Class = &[
- ('\U00000009', '\U0000000a'),
- ('\U0000000c', '\U0000000d'),
- ('\U00000020', '\U00000020'),
- ('\U000000a0', '\U000000a0'),
- ('\U00001680', '\U00001680'),
- ('\U00002000', '\U0000200a'),
- ('\U00002028', '\U00002029'),
- ('\U0000202f', '\U0000202f'),
- ('\U0000205f', '\U0000205f'),
- ('\U00003000', '\U00003000')
-];
-
-pub static PERLW: Class = &[
- ('\U00000030', '\U00000039'),
- ('\U00000041', '\U0000005a'),
- ('\U0000005f', '\U0000005f'),
- ('\U00000061', '\U0000007a'),
- ('\U000000aa', '\U000000aa'),
- ('\U000000b5', '\U000000b5'),
- ('\U000000ba', '\U000000ba'),
- ('\U000000c0', '\U000000d6'),
- ('\U000000d8', '\U000000f6'),
- ('\U000000f8', '\U000002c1'),
- ('\U000002c6', '\U000002d1'),
- ('\U000002e0', '\U000002e4'),
- ('\U000002ec', '\U000002ec'),
- ('\U000002ee', '\U000002ee'),
- ('\U00000370', '\U00000374'),
- ('\U00000376', '\U00000377'),
- ('\U0000037a', '\U0000037d'),
- ('\U00000386', '\U00000386'),
- ('\U00000388', '\U0000038a'),
- ('\U0000038c', '\U0000038c'),
- ('\U0000038e', '\U000003a1'),
- ('\U000003a3', '\U000003f5'),
- ('\U000003f7', '\U00000481'),
- ('\U0000048a', '\U00000527'),
- ('\U00000531', '\U00000556'),
- ('\U00000559', '\U00000559'),
- ('\U00000561', '\U00000587'),
- ('\U000005d0', '\U000005ea'),
- ('\U000005f0', '\U000005f2'),
- ('\U00000620', '\U0000064a'),
- ('\U0000066e', '\U0000066f'),
- ('\U00000671', '\U000006d3'),
- ('\U000006d5', '\U000006d5'),
- ('\U000006e5', '\U000006e6'),
- ('\U000006ee', '\U000006ef'),
- ('\U000006fa', '\U000006fc'),
- ('\U000006ff', '\U000006ff'),
- ('\U00000710', '\U00000710'),
- ('\U00000712', '\U0000072f'),
- ('\U0000074d', '\U000007a5'),
- ('\U000007b1', '\U000007b1'),
- ('\U000007ca', '\U000007ea'),
- ('\U000007f4', '\U000007f5'),
- ('\U000007fa', '\U000007fa'),
- ('\U00000800', '\U00000815'),
- ('\U0000081a', '\U0000081a'),
- ('\U00000824', '\U00000824'),
- ('\U00000828', '\U00000828'),
- ('\U00000840', '\U00000858'),
- ('\U000008a0', '\U000008a0'),
- ('\U000008a2', '\U000008ac'),
- ('\U00000904', '\U00000939'),
- ('\U0000093d', '\U0000093d'),
- ('\U00000950', '\U00000950'),
- ('\U00000958', '\U00000961'),
- ('\U00000971', '\U00000977'),
- ('\U00000979', '\U0000097f'),
- ('\U00000985', '\U0000098c'),
- ('\U0000098f', '\U00000990'),
- ('\U00000993', '\U000009a8'),
- ('\U000009aa', '\U000009b0'),
- ('\U000009b2', '\U000009b2'),
- ('\U000009b6', '\U000009b9'),
- ('\U000009bd', '\U000009bd'),
- ('\U000009ce', '\U000009ce'),
- ('\U000009dc', '\U000009dd'),
- ('\U000009df', '\U000009e1'),
- ('\U000009f0', '\U000009f1'),
- ('\U00000a05', '\U00000a0a'),
- ('\U00000a0f', '\U00000a10'),
- ('\U00000a13', '\U00000a28'),
- ('\U00000a2a', '\U00000a30'),
- ('\U00000a32', '\U00000a33'),
- ('\U00000a35', '\U00000a36'),
- ('\U00000a38', '\U00000a39'),
- ('\U00000a59', '\U00000a5c'),
- ('\U00000a5e', '\U00000a5e'),
- ('\U00000a72', '\U00000a74'),
- ('\U00000a85', '\U00000a8d'),
- ('\U00000a8f', '\U00000a91'),
- ('\U00000a93', '\U00000aa8'),
- ('\U00000aaa', '\U00000ab0'),
- ('\U00000ab2', '\U00000ab3'),
- ('\U00000ab5', '\U00000ab9'),
- ('\U00000abd', '\U00000abd'),
- ('\U00000ad0', '\U00000ad0'),
- ('\U00000ae0', '\U00000ae1'),
- ('\U00000b05', '\U00000b0c'),
- ('\U00000b0f', '\U00000b10'),
- ('\U00000b13', '\U00000b28'),
- ('\U00000b2a', '\U00000b30'),
- ('\U00000b32', '\U00000b33'),
- ('\U00000b35', '\U00000b39'),
- ('\U00000b3d', '\U00000b3d'),
- ('\U00000b5c', '\U00000b5d'),
- ('\U00000b5f', '\U00000b61'),
- ('\U00000b71', '\U00000b71'),
- ('\U00000b83', '\U00000b83'),
- ('\U00000b85', '\U00000b8a'),
- ('\U00000b8e', '\U00000b90'),
- ('\U00000b92', '\U00000b95'),
- ('\U00000b99', '\U00000b9a'),
- ('\U00000b9c', '\U00000b9c'),
- ('\U00000b9e', '\U00000b9f'),
- ('\U00000ba3', '\U00000ba4'),
- ('\U00000ba8', '\U00000baa'),
- ('\U00000bae', '\U00000bb9'),
- ('\U00000bd0', '\U00000bd0'),
- ('\U00000c05', '\U00000c0c'),
- ('\U00000c0e', '\U00000c10'),
- ('\U00000c12', '\U00000c28'),
- ('\U00000c2a', '\U00000c33'),
- ('\U00000c35', '\U00000c39'),
- ('\U00000c3d', '\U00000c3d'),
- ('\U00000c58', '\U00000c59'),
- ('\U00000c60', '\U00000c61'),
- ('\U00000c85', '\U00000c8c'),
- ('\U00000c8e', '\U00000c90'),
- ('\U00000c92', '\U00000ca8'),
- ('\U00000caa', '\U00000cb3'),
- ('\U00000cb5', '\U00000cb9'),
- ('\U00000cbd', '\U00000cbd'),
- ('\U00000cde', '\U00000cde'),
- ('\U00000ce0', '\U00000ce1'),
- ('\U00000cf1', '\U00000cf2'),
- ('\U00000d05', '\U00000d0c'),
- ('\U00000d0e', '\U00000d10'),
- ('\U00000d12', '\U00000d3a'),
- ('\U00000d3d', '\U00000d3d'),
- ('\U00000d4e', '\U00000d4e'),
- ('\U00000d60', '\U00000d61'),
- ('\U00000d7a', '\U00000d7f'),
- ('\U00000d85', '\U00000d96'),
- ('\U00000d9a', '\U00000db1'),
- ('\U00000db3', '\U00000dbb'),
- ('\U00000dbd', '\U00000dbd'),
- ('\U00000dc0', '\U00000dc6'),
- ('\U00000e01', '\U00000e30'),
- ('\U00000e32', '\U00000e33'),
- ('\U00000e40', '\U00000e46'),
- ('\U00000e81', '\U00000e82'),
- ('\U00000e84', '\U00000e84'),
- ('\U00000e87', '\U00000e88'),
- ('\U00000e8a', '\U00000e8a'),
- ('\U00000e8d', '\U00000e8d'),
- ('\U00000e94', '\U00000e97'),
- ('\U00000e99', '\U00000e9f'),
- ('\U00000ea1', '\U00000ea3'),
- ('\U00000ea5', '\U00000ea5'),
- ('\U00000ea7', '\U00000ea7'),
- ('\U00000eaa', '\U00000eab'),
- ('\U00000ead', '\U00000eb0'),
- ('\U00000eb2', '\U00000eb3'),
- ('\U00000ebd', '\U00000ebd'),
- ('\U00000ec0', '\U00000ec4'),
- ('\U00000ec6', '\U00000ec6'),
- ('\U00000edc', '\U00000edf'),
- ('\U00000f00', '\U00000f00'),
- ('\U00000f40', '\U00000f47'),
- ('\U00000f49', '\U00000f6c'),
- ('\U00000f88', '\U00000f8c'),
- ('\U00001000', '\U0000102a'),
- ('\U0000103f', '\U0000103f'),
- ('\U00001050', '\U00001055'),
- ('\U0000105a', '\U0000105d'),
- ('\U00001061', '\U00001061'),
- ('\U00001065', '\U00001066'),
- ('\U0000106e', '\U00001070'),
- ('\U00001075', '\U00001081'),
- ('\U0000108e', '\U0000108e'),
- ('\U000010a0', '\U000010c5'),
- ('\U000010c7', '\U000010c7'),
- ('\U000010cd', '\U000010cd'),
- ('\U000010d0', '\U000010fa'),
- ('\U000010fc', '\U00001248'),
- ('\U0000124a', '\U0000124d'),
- ('\U00001250', '\U00001256'),
- ('\U00001258', '\U00001258'),
- ('\U0000125a', '\U0000125d'),
- ('\U00001260', '\U00001288'),
- ('\U0000128a', '\U0000128d'),
- ('\U00001290', '\U000012b0'),
- ('\U000012b2', '\U000012b5'),
- ('\U000012b8', '\U000012be'),
- ('\U000012c0', '\U000012c0'),
- ('\U000012c2', '\U000012c5'),
- ('\U000012c8', '\U000012d6'),
- ('\U000012d8', '\U00001310'),
- ('\U00001312', '\U00001315'),
- ('\U00001318', '\U0000135a'),
- ('\U00001380', '\U0000138f'),
- ('\U000013a0', '\U000013f4'),
- ('\U00001401', '\U0000166c'),
- ('\U0000166f', '\U0000167f'),
- ('\U00001681', '\U0000169a'),
- ('\U000016a0', '\U000016ea'),
- ('\U00001700', '\U0000170c'),
- ('\U0000170e', '\U00001711'),
- ('\U00001720', '\U00001731'),
- ('\U00001740', '\U00001751'),
- ('\U00001760', '\U0000176c'),
- ('\U0000176e', '\U00001770'),
- ('\U00001780', '\U000017b3'),
- ('\U000017d7', '\U000017d7'),
- ('\U000017dc', '\U000017dc'),
- ('\U00001820', '\U00001877'),
- ('\U00001880', '\U000018a8'),
- ('\U000018aa', '\U000018aa'),
- ('\U000018b0', '\U000018f5'),
- ('\U00001900', '\U0000191c'),
- ('\U00001950', '\U0000196d'),
- ('\U00001970', '\U00001974'),
- ('\U00001980', '\U000019ab'),
- ('\U000019c1', '\U000019c7'),
- ('\U00001a00', '\U00001a16'),
- ('\U00001a20', '\U00001a54'),
- ('\U00001aa7', '\U00001aa7'),
- ('\U00001b05', '\U00001b33'),
- ('\U00001b45', '\U00001b4b'),
- ('\U00001b83', '\U00001ba0'),
- ('\U00001bae', '\U00001baf'),
- ('\U00001bba', '\U00001be5'),
- ('\U00001c00', '\U00001c23'),
- ('\U00001c4d', '\U00001c4f'),
- ('\U00001c5a', '\U00001c7d'),
- ('\U00001ce9', '\U00001cec'),
- ('\U00001cee', '\U00001cf1'),
- ('\U00001cf5', '\U00001cf6'),
- ('\U00001d00', '\U00001dbf'),
- ('\U00001e00', '\U00001f15'),
- ('\U00001f18', '\U00001f1d'),
- ('\U00001f20', '\U00001f45'),
- ('\U00001f48', '\U00001f4d'),
- ('\U00001f50', '\U00001f57'),
- ('\U00001f59', '\U00001f59'),
- ('\U00001f5b', '\U00001f5b'),
- ('\U00001f5d', '\U00001f5d'),
- ('\U00001f5f', '\U00001f7d'),
- ('\U00001f80', '\U00001fb4'),
- ('\U00001fb6', '\U00001fbc'),
- ('\U00001fbe', '\U00001fbe'),
- ('\U00001fc2', '\U00001fc4'),
- ('\U00001fc6', '\U00001fcc'),
- ('\U00001fd0', '\U00001fd3'),
- ('\U00001fd6', '\U00001fdb'),
- ('\U00001fe0', '\U00001fec'),
- ('\U00001ff2', '\U00001ff4'),
- ('\U00001ff6', '\U00001ffc'),
- ('\U00002071', '\U00002071'),
- ('\U0000207f', '\U0000207f'),
- ('\U00002090', '\U0000209c'),
- ('\U00002102', '\U00002102'),
- ('\U00002107', '\U00002107'),
- ('\U0000210a', '\U00002113'),
- ('\U00002115', '\U00002115'),
- ('\U00002119', '\U0000211d'),
- ('\U00002124', '\U00002124'),
- ('\U00002126', '\U00002126'),
- ('\U00002128', '\U00002128'),
- ('\U0000212a', '\U0000212d'),
- ('\U0000212f', '\U00002139'),
- ('\U0000213c', '\U0000213f'),
- ('\U00002145', '\U00002149'),
- ('\U0000214e', '\U0000214e'),
- ('\U00002183', '\U00002184'),
- ('\U00002c00', '\U00002c2e'),
- ('\U00002c30', '\U00002c5e'),
- ('\U00002c60', '\U00002ce4'),
- ('\U00002ceb', '\U00002cee'),
- ('\U00002cf2', '\U00002cf3'),
- ('\U00002d00', '\U00002d25'),
- ('\U00002d27', '\U00002d27'),
- ('\U00002d2d', '\U00002d2d'),
- ('\U00002d30', '\U00002d67'),
- ('\U00002d6f', '\U00002d6f'),
- ('\U00002d80', '\U00002d96'),
- ('\U00002da0', '\U00002da6'),
- ('\U00002da8', '\U00002dae'),
- ('\U00002db0', '\U00002db6'),
- ('\U00002db8', '\U00002dbe'),
- ('\U00002dc0', '\U00002dc6'),
- ('\U00002dc8', '\U00002dce'),
- ('\U00002dd0', '\U00002dd6'),
- ('\U00002dd8', '\U00002dde'),
- ('\U00002e2f', '\U00002e2f'),
- ('\U00003005', '\U00003006'),
- ('\U00003031', '\U00003035'),
- ('\U0000303b', '\U0000303c'),
- ('\U00003041', '\U00003096'),
- ('\U0000309d', '\U0000309f'),
- ('\U000030a1', '\U000030fa'),
- ('\U000030fc', '\U000030ff'),
- ('\U00003105', '\U0000312d'),
- ('\U00003131', '\U0000318e'),
- ('\U000031a0', '\U000031ba'),
- ('\U000031f0', '\U000031ff'),
- ('\U00003400', '\U00003400'),
- ('\U00004db5', '\U00004db5'),
- ('\U00004e00', '\U00004e00'),
- ('\U00009fcc', '\U00009fcc'),
- ('\U0000a000', '\U0000a48c'),
- ('\U0000a4d0', '\U0000a4fd'),
- ('\U0000a500', '\U0000a60c'),
- ('\U0000a610', '\U0000a61f'),
- ('\U0000a62a', '\U0000a62b'),
- ('\U0000a640', '\U0000a66e'),
- ('\U0000a67f', '\U0000a697'),
- ('\U0000a6a0', '\U0000a6e5'),
- ('\U0000a717', '\U0000a71f'),
- ('\U0000a722', '\U0000a788'),
- ('\U0000a78b', '\U0000a78e'),
- ('\U0000a790', '\U0000a793'),
- ('\U0000a7a0', '\U0000a7aa'),
- ('\U0000a7f8', '\U0000a801'),
- ('\U0000a803', '\U0000a805'),
- ('\U0000a807', '\U0000a80a'),
- ('\U0000a80c', '\U0000a822'),
- ('\U0000a840', '\U0000a873'),
- ('\U0000a882', '\U0000a8b3'),
- ('\U0000a8f2', '\U0000a8f7'),
- ('\U0000a8fb', '\U0000a8fb'),
- ('\U0000a90a', '\U0000a925'),
- ('\U0000a930', '\U0000a946'),
- ('\U0000a960', '\U0000a97c'),
- ('\U0000a984', '\U0000a9b2'),
- ('\U0000a9cf', '\U0000a9cf'),
- ('\U0000aa00', '\U0000aa28'),
- ('\U0000aa40', '\U0000aa42'),
- ('\U0000aa44', '\U0000aa4b'),
- ('\U0000aa60', '\U0000aa76'),
- ('\U0000aa7a', '\U0000aa7a'),
- ('\U0000aa80', '\U0000aaaf'),
- ('\U0000aab1', '\U0000aab1'),
- ('\U0000aab5', '\U0000aab6'),
- ('\U0000aab9', '\U0000aabd'),
- ('\U0000aac0', '\U0000aac0'),
- ('\U0000aac2', '\U0000aac2'),
- ('\U0000aadb', '\U0000aadd'),
- ('\U0000aae0', '\U0000aaea'),
- ('\U0000aaf2', '\U0000aaf4'),
- ('\U0000ab01', '\U0000ab06'),
- ('\U0000ab09', '\U0000ab0e'),
- ('\U0000ab11', '\U0000ab16'),
- ('\U0000ab20', '\U0000ab26'),
- ('\U0000ab28', '\U0000ab2e'),
- ('\U0000abc0', '\U0000abe2'),
- ('\U0000ac00', '\U0000ac00'),
- ('\U0000d7a3', '\U0000d7a3'),
- ('\U0000d7b0', '\U0000d7c6'),
- ('\U0000d7cb', '\U0000d7fb'),
- ('\U0000f900', '\U0000fa6d'),
- ('\U0000fa70', '\U0000fad9'),
- ('\U0000fb00', '\U0000fb06'),
- ('\U0000fb13', '\U0000fb17'),
- ('\U0000fb1d', '\U0000fb1d'),
- ('\U0000fb1f', '\U0000fb28'),
- ('\U0000fb2a', '\U0000fb36'),
- ('\U0000fb38', '\U0000fb3c'),
- ('\U0000fb3e', '\U0000fb3e'),
- ('\U0000fb40', '\U0000fb41'),
- ('\U0000fb43', '\U0000fb44'),
- ('\U0000fb46', '\U0000fbb1'),
- ('\U0000fbd3', '\U0000fd3d'),
- ('\U0000fd50', '\U0000fd8f'),
- ('\U0000fd92', '\U0000fdc7'),
- ('\U0000fdf0', '\U0000fdfb'),
- ('\U0000fe70', '\U0000fe74'),
- ('\U0000fe76', '\U0000fefc'),
- ('\U0000ff21', '\U0000ff3a'),
- ('\U0000ff41', '\U0000ff5a'),
- ('\U0000ff66', '\U0000ffbe'),
- ('\U0000ffc2', '\U0000ffc7'),
- ('\U0000ffca', '\U0000ffcf'),
- ('\U0000ffd2', '\U0000ffd7'),
- ('\U0000ffda', '\U0000ffdc'),
- ('\U00010000', '\U0001000b'),
- ('\U0001000d', '\U00010026'),
- ('\U00010028', '\U0001003a'),
- ('\U0001003c', '\U0001003d'),
- ('\U0001003f', '\U0001004d'),
- ('\U00010050', '\U0001005d'),
- ('\U00010080', '\U000100fa'),
- ('\U00010280', '\U0001029c'),
- ('\U000102a0', '\U000102d0'),
- ('\U00010300', '\U0001031e'),
- ('\U00010330', '\U00010340'),
- ('\U00010342', '\U00010349'),
- ('\U00010380', '\U0001039d'),
- ('\U000103a0', '\U000103c3'),
- ('\U000103c8', '\U000103cf'),
- ('\U00010400', '\U0001049d'),
- ('\U00010800', '\U00010805'),
- ('\U00010808', '\U00010808'),
- ('\U0001080a', '\U00010835'),
- ('\U00010837', '\U00010838'),
- ('\U0001083c', '\U0001083c'),
- ('\U0001083f', '\U00010855'),
- ('\U00010900', '\U00010915'),
- ('\U00010920', '\U00010939'),
- ('\U00010980', '\U000109b7'),
- ('\U000109be', '\U000109bf'),
- ('\U00010a00', '\U00010a00'),
- ('\U00010a10', '\U00010a13'),
- ('\U00010a15', '\U00010a17'),
- ('\U00010a19', '\U00010a33'),
- ('\U00010a60', '\U00010a7c'),
- ('\U00010b00', '\U00010b35'),
- ('\U00010b40', '\U00010b55'),
- ('\U00010b60', '\U00010b72'),
- ('\U00010c00', '\U00010c48'),
- ('\U00011003', '\U00011037'),
- ('\U00011083', '\U000110af'),
- ('\U000110d0', '\U000110e8'),
- ('\U00011103', '\U00011126'),
- ('\U00011183', '\U000111b2'),
- ('\U000111c1', '\U000111c4'),
- ('\U00011680', '\U000116aa'),
- ('\U00012000', '\U0001236e'),
- ('\U00013000', '\U0001342e'),
- ('\U00016800', '\U00016a38'),
- ('\U00016f00', '\U00016f44'),
- ('\U00016f50', '\U00016f50'),
- ('\U00016f93', '\U00016f9f'),
- ('\U0001b000', '\U0001b001'),
- ('\U0001d400', '\U0001d454'),
- ('\U0001d456', '\U0001d49c'),
- ('\U0001d49e', '\U0001d49f'),
- ('\U0001d4a2', '\U0001d4a2'),
- ('\U0001d4a5', '\U0001d4a6'),
- ('\U0001d4a9', '\U0001d4ac'),
- ('\U0001d4ae', '\U0001d4b9'),
- ('\U0001d4bb', '\U0001d4bb'),
- ('\U0001d4bd', '\U0001d4c3'),
- ('\U0001d4c5', '\U0001d505'),
- ('\U0001d507', '\U0001d50a'),
- ('\U0001d50d', '\U0001d514'),
- ('\U0001d516', '\U0001d51c'),
- ('\U0001d51e', '\U0001d539'),
- ('\U0001d53b', '\U0001d53e'),
- ('\U0001d540', '\U0001d544'),
- ('\U0001d546', '\U0001d546'),
- ('\U0001d54a', '\U0001d550'),
- ('\U0001d552', '\U0001d6a5'),
- ('\U0001d6a8', '\U0001d6c0'),
- ('\U0001d6c2', '\U0001d6da'),
- ('\U0001d6dc', '\U0001d6fa'),
- ('\U0001d6fc', '\U0001d714'),
- ('\U0001d716', '\U0001d734'),
- ('\U0001d736', '\U0001d74e'),
- ('\U0001d750', '\U0001d76e'),
- ('\U0001d770', '\U0001d788'),
- ('\U0001d78a', '\U0001d7a8'),
- ('\U0001d7aa', '\U0001d7c2'),
- ('\U0001d7c4', '\U0001d7cb'),
- ('\U0001ee00', '\U0001ee03'),
- ('\U0001ee05', '\U0001ee1f'),
- ('\U0001ee21', '\U0001ee22'),
- ('\U0001ee24', '\U0001ee24'),
- ('\U0001ee27', '\U0001ee27'),
- ('\U0001ee29', '\U0001ee32'),
- ('\U0001ee34', '\U0001ee37'),
- ('\U0001ee39', '\U0001ee39'),
- ('\U0001ee3b', '\U0001ee3b'),
- ('\U0001ee42', '\U0001ee42'),
- ('\U0001ee47', '\U0001ee47'),
- ('\U0001ee49', '\U0001ee49'),
- ('\U0001ee4b', '\U0001ee4b'),
- ('\U0001ee4d', '\U0001ee4f'),
- ('\U0001ee51', '\U0001ee52'),
- ('\U0001ee54', '\U0001ee54'),
- ('\U0001ee57', '\U0001ee57'),
- ('\U0001ee59', '\U0001ee59'),
- ('\U0001ee5b', '\U0001ee5b'),
- ('\U0001ee5d', '\U0001ee5d'),
- ('\U0001ee5f', '\U0001ee5f'),
- ('\U0001ee61', '\U0001ee62'),
- ('\U0001ee64', '\U0001ee64'),
- ('\U0001ee67', '\U0001ee6a'),
- ('\U0001ee6c', '\U0001ee72'),
- ('\U0001ee74', '\U0001ee77'),
- ('\U0001ee79', '\U0001ee7c'),
- ('\U0001ee7e', '\U0001ee7e'),
- ('\U0001ee80', '\U0001ee89'),
- ('\U0001ee8b', '\U0001ee9b'),
- ('\U0001eea1', '\U0001eea3'),
- ('\U0001eea5', '\U0001eea9'),
- ('\U0001eeab', '\U0001eebb'),
- ('\U00020000', '\U00020000'),
- ('\U0002a6d6', '\U0002a6d6'),
- ('\U0002a700', '\U0002a700'),
- ('\U0002b734', '\U0002b734'),
- ('\U0002b740', '\U0002b740'),
- ('\U0002b81d', '\U0002b81d'),
- ('\U0002f800', '\U0002fa1d')
-];
-
// Test the Unicode friendliness of Perl character classes.
mat!(uni_perl_w, r"\w+", "dδd", Some((0, 4)))
-mat!(uni_perl_w_not, r"\w+", "â\85¡", None)
-mat!(uni_perl_w_neg, r"\W+", "â\85¡", Some((0, 3)))
+mat!(uni_perl_w_not, r"\w+", "⥡", None)
+mat!(uni_perl_w_neg, r"\W+", "⥡", Some((0, 3)))
mat!(uni_perl_d, r"\d+", "1२३9", Some((0, 8)))
mat!(uni_perl_d_not, r"\d+", "Ⅱ", None)
mat!(uni_perl_d_neg, r"\D+", "Ⅱ", Some((0, 3)))
Save, Jump, Split,
};
use parse::{FLAG_NOCASE, FLAG_MULTI, FLAG_DOTNL, FLAG_NEGATED};
-use parse::unicode::PERLW;
+use unicode::regex::PERLW;
pub type CaptureLocs = Vec<Option<uint>>;
//! This crate provides the `regex!` macro. Its use is documented in the
//! `regex` crate.
-#![crate_id = "regex_macros#0.11.0"]
+#![crate_name = "regex_macros"]
#![crate_type = "dylib"]
#![experimental]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+ html_root_url = "http://doc.rust-lang.org/master/")]
#![feature(plugin_registrar, managed_boxes, quote)]
let re = match Regex::new(regex.as_slice()) {
Ok(re) => re,
Err(err) => {
- cx.span_err(sp, err.to_str().as_slice());
+ cx.span_err(sp, err.to_string().as_slice());
return DummyResult::any(sp)
}
};
#[inline]
fn groups<'r>(&'r mut self, i: uint) -> &'r mut Captures {
- &'r mut self.queue[i].groups
+ &mut self.queue[i].groups
}
}
}
let regex = match entry.node {
ast::ExprLit(lit) => {
match lit.node {
- ast::LitStr(ref s, _) => s.to_str(),
+ ast::LitStr(ref s, _) => s.to_string(),
_ => {
cx.span_err(entry.span, format!(
"expected string literal but got `{}`",
- pprust::lit_to_str(lit)).as_slice());
+ pprust::lit_to_string(lit)).as_slice());
return None
}
}
_ => {
cx.span_err(entry.span, format!(
"expected string literal but got `{}`",
- pprust::expr_to_str(entry)).as_slice());
+ pprust::expr_to_string(entry)).as_slice());
return None
}
};
//! necessary. It is an error to include this library when also linking with
//! the system libc library.
-#![crate_id = "rlibc#0.11.0"]
+#![crate_name = "rlibc"]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+ html_root_url = "http://doc.rust-lang.org/master/")]
#![feature(intrinsics)]
#![no_std]
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub static box_field_refcnt: uint = 0u;
-pub static box_field_tydesc: uint = 1u;
-pub static box_field_body: uint = 4u;
-
-pub static tydesc_field_visit_glue: uint = 3u;
-
-// The two halves of a closure: code and environment.
-pub static fn_field_code: uint = 0u;
-pub static fn_field_box: uint = 1u;
-
-// The two fields of a trait object/trait instance: vtable and box.
-// The vtable contains the type descriptor as first element.
-pub static trt_field_vtable: uint = 0u;
-pub static trt_field_box: uint = 1u;
-
-pub static vec_elt_fill: uint = 0u;
-
-pub static vec_elt_alloc: uint = 1u;
-
-pub static vec_elt_elems: uint = 2u;
-
-pub static slice_elt_base: uint = 0u;
-pub static slice_elt_len: uint = 1u;
+++ /dev/null
-// Copyright 2013-2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A helper class for dealing with static archives
-
-use back::link::{get_ar_prog};
-use driver::session::Session;
-use metadata::filesearch;
-use lib::llvm::{ArchiveRef, llvm};
-
-use libc;
-use std::io::process::{Command, ProcessOutput};
-use std::io::{fs, TempDir};
-use std::io;
-use std::mem;
-use std::os;
-use std::raw;
-use std::str;
-use syntax::abi;
-
-pub static METADATA_FILENAME: &'static str = "rust.metadata.bin";
-
-pub struct Archive<'a> {
- sess: &'a Session,
- dst: Path,
-}
-
-pub struct ArchiveRO {
- ptr: ArchiveRef,
-}
-
-fn run_ar(sess: &Session, args: &str, cwd: Option<&Path>,
- paths: &[&Path]) -> ProcessOutput {
- let ar = get_ar_prog(sess);
- let mut cmd = Command::new(ar.as_slice());
-
- cmd.arg(args).args(paths);
- debug!("{}", cmd);
-
- match cwd {
- Some(p) => {
- cmd.cwd(p);
- debug!("inside {}", p.display());
- }
- None => {}
- }
-
- match cmd.spawn() {
- Ok(prog) => {
- let o = prog.wait_with_output().unwrap();
- if !o.status.success() {
- sess.err(format!("{} failed with: {}",
- cmd,
- o.status).as_slice());
- sess.note(format!("stdout ---\n{}",
- str::from_utf8(o.output
- .as_slice()).unwrap())
- .as_slice());
- sess.note(format!("stderr ---\n{}",
- str::from_utf8(o.error
- .as_slice()).unwrap())
- .as_slice());
- sess.abort_if_errors();
- }
- o
- },
- Err(e) => {
- sess.err(format!("could not exec `{}`: {}", ar.as_slice(),
- e).as_slice());
- sess.abort_if_errors();
- fail!("rustc::back::archive::run_ar() should not reach this point");
- }
- }
-}
-
-impl<'a> Archive<'a> {
- /// Initializes a new static archive with the given object file
- pub fn create<'b>(sess: &'a Session, dst: &'b Path,
- initial_object: &'b Path) -> Archive<'a> {
- run_ar(sess, "crus", None, [dst, initial_object]);
- Archive { sess: sess, dst: dst.clone() }
- }
-
- /// Opens an existing static archive
- pub fn open(sess: &'a Session, dst: Path) -> Archive<'a> {
- assert!(dst.exists());
- Archive { sess: sess, dst: dst }
- }
-
- /// Adds all of the contents of a native library to this archive. This will
- /// search in the relevant locations for a library named `name`.
- pub fn add_native_library(&mut self, name: &str) -> io::IoResult<()> {
- let location = self.find_library(name);
- self.add_archive(&location, name, [])
- }
-
- /// Adds all of the contents of the rlib at the specified path to this
- /// archive.
- ///
- /// This ignores adding the bytecode from the rlib, and if LTO is enabled
- /// then the object file also isn't added.
- pub fn add_rlib(&mut self, rlib: &Path, name: &str,
- lto: bool) -> io::IoResult<()> {
- let object = format!("{}.o", name);
- let bytecode = format!("{}.bytecode.deflate", name);
- let mut ignore = vec!(bytecode.as_slice(), METADATA_FILENAME);
- if lto {
- ignore.push(object.as_slice());
- }
- self.add_archive(rlib, name, ignore.as_slice())
- }
-
- /// Adds an arbitrary file to this archive
- pub fn add_file(&mut self, file: &Path, has_symbols: bool) {
- let cmd = if has_symbols {"r"} else {"rS"};
- run_ar(self.sess, cmd, None, [&self.dst, file]);
- }
-
- /// Removes a file from this archive
- pub fn remove_file(&mut self, file: &str) {
- run_ar(self.sess, "d", None, [&self.dst, &Path::new(file)]);
- }
-
- /// Updates all symbols in the archive (runs 'ar s' over it)
- pub fn update_symbols(&mut self) {
- run_ar(self.sess, "s", None, [&self.dst]);
- }
-
- /// Lists all files in an archive
- pub fn files(&self) -> Vec<String> {
- let output = run_ar(self.sess, "t", None, [&self.dst]);
- let output = str::from_utf8(output.output.as_slice()).unwrap();
- // use lines_any because windows delimits output with `\r\n` instead of
- // just `\n`
- output.lines_any().map(|s| s.to_string()).collect()
- }
-
- fn add_archive(&mut self, archive: &Path, name: &str,
- skip: &[&str]) -> io::IoResult<()> {
- let loc = TempDir::new("rsar").unwrap();
-
- // First, extract the contents of the archive to a temporary directory
- let archive = os::make_absolute(archive);
- run_ar(self.sess, "x", Some(loc.path()), [&archive]);
-
- // Next, we must rename all of the inputs to "guaranteed unique names".
- // The reason for this is that archives are keyed off the name of the
- // files, so if two files have the same name they will override one
- // another in the archive (bad).
- //
- // We skip any files explicitly desired for skipping, and we also skip
- // all SYMDEF files as these are just magical placeholders which get
- // re-created when we make a new archive anyway.
- let files = try!(fs::readdir(loc.path()));
- let mut inputs = Vec::new();
- for file in files.iter() {
- let filename = file.filename_str().unwrap();
- if skip.iter().any(|s| *s == filename) { continue }
- if filename.contains(".SYMDEF") { continue }
-
- let filename = format!("r-{}-{}", name, filename);
- // LLDB (as mentioned in back::link) crashes on filenames of exactly
- // 16 bytes in length. If we're including an object file with
- // exactly 16-bytes of characters, give it some prefix so that it's
- // not 16 bytes.
- let filename = if filename.len() == 16 {
- format!("lldb-fix-{}", filename)
- } else {
- filename
- };
- let new_filename = file.with_filename(filename);
- try!(fs::rename(file, &new_filename));
- inputs.push(new_filename);
- }
- if inputs.len() == 0 { return Ok(()) }
-
- // Finally, add all the renamed files to this archive
- let mut args = vec!(&self.dst);
- args.extend(inputs.iter());
- run_ar(self.sess, "r", None, args.as_slice());
- Ok(())
- }
-
- fn find_library(&self, name: &str) -> Path {
- let (osprefix, osext) = match self.sess.targ_cfg.os {
- abi::OsWin32 => ("", "lib"), _ => ("lib", "a"),
- };
- // On Windows, static libraries sometimes show up as libfoo.a and other
- // times show up as foo.lib
- let oslibname = format!("{}{}.{}", osprefix, name, osext);
- let unixlibname = format!("lib{}.a", name);
-
- let mut rustpath = filesearch::rust_path();
- rustpath.push(self.sess.target_filesearch().get_lib_path());
- let search = self.sess.opts.addl_lib_search_paths.borrow();
- for path in search.iter().chain(rustpath.iter()) {
- debug!("looking for {} inside {}", name, path.display());
- let test = path.join(oslibname.as_slice());
- if test.exists() { return test }
- if oslibname != unixlibname {
- let test = path.join(unixlibname.as_slice());
- if test.exists() { return test }
- }
- }
- self.sess.fatal(format!("could not find native static library `{}`, \
- perhaps an -L flag is missing?",
- name).as_slice());
- }
-}
-
-impl ArchiveRO {
- /// Opens a static archive for read-only purposes. This is more optimized
- /// than the `open` method because it uses LLVM's internal `Archive` class
- /// rather than shelling out to `ar` for everything.
- ///
- /// If this archive is used with a mutable method, then an error will be
- /// raised.
- pub fn open(dst: &Path) -> Option<ArchiveRO> {
- unsafe {
- let ar = dst.with_c_str(|dst| {
- llvm::LLVMRustOpenArchive(dst)
- });
- if ar.is_null() {
- None
- } else {
- Some(ArchiveRO { ptr: ar })
- }
- }
- }
-
- /// Reads a file in the archive
- pub fn read<'a>(&'a self, file: &str) -> Option<&'a [u8]> {
- unsafe {
- let mut size = 0 as libc::size_t;
- let ptr = file.with_c_str(|file| {
- llvm::LLVMRustArchiveReadSection(self.ptr, file, &mut size)
- });
- if ptr.is_null() {
- None
- } else {
- Some(mem::transmute(raw::Slice {
- data: ptr,
- len: size as uint,
- }))
- }
- }
- }
-}
-
-impl Drop for ArchiveRO {
- fn drop(&mut self) {
- unsafe {
- llvm::LLVMRustDestroyArchive(self.ptr);
- }
- }
-}
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use back::target_strs;
-use syntax::abi;
-
-pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
- let cc_args = if target_triple.as_slice().contains("thumb") {
- vec!("-mthumb".to_string())
- } else {
- vec!("-marm".to_string())
- };
- return target_strs::t {
- module_asm: "".to_string(),
-
- data_layout: match target_os {
- abi::OsMacos => {
- "e-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
-
- abi::OsiOS => {
- "e-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
-
- abi::OsWin32 => {
- "e-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
-
- abi::OsLinux => {
- "e-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
-
- abi::OsAndroid => {
- "e-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
-
- abi::OsFreebsd => {
- "e-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
- },
-
- target_triple: target_triple,
-
- cc_args: cc_args,
- };
-}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use back::archive::{Archive, METADATA_FILENAME};
-use back::rpath;
-use back::svh::Svh;
-use driver::driver::{CrateTranslation, OutputFilenames};
+use super::archive::{Archive, ArchiveConfig, METADATA_FILENAME};
+use super::rpath;
+use super::rpath::RPathConfig;
+use super::svh::Svh;
+use driver::driver::{CrateTranslation, OutputFilenames, Input, FileInput};
use driver::config::NoDebugInfo;
use driver::session::Session;
use driver::config;
-use lib::llvm::llvm;
-use lib::llvm::ModuleRef;
-use lib;
+use llvm;
+use llvm::ModuleRef;
use metadata::common::LinkMeta;
-use metadata::{encoder, cstore, filesearch, csearch, loader};
+use metadata::{encoder, cstore, filesearch, csearch, loader, creader};
use middle::trans::context::CrateContext;
use middle::trans::common::gensym_name;
use middle::ty;
use std::c_str::{ToCStr, CString};
use std::char;
+use std::collections::HashSet;
use std::io::{fs, TempDir, Command};
use std::io;
use std::ptr;
use syntax::ast;
use syntax::ast_map::{PathElem, PathElems, PathName};
use syntax::ast_map;
-use syntax::attr;
use syntax::attr::AttrMetaMethods;
-use syntax::crateid::CrateId;
+use syntax::codemap::Span;
use syntax::parse::token;
#[deriving(Clone, PartialEq, PartialOrd, Ord, Eq)]
pub fn write_output_file(
sess: &Session,
- target: lib::llvm::TargetMachineRef,
- pm: lib::llvm::PassManagerRef,
+ target: llvm::TargetMachineRef,
+ pm: llvm::PassManagerRef,
m: ModuleRef,
output: &Path,
- file_type: lib::llvm::FileType) {
+ file_type: llvm::FileType) {
unsafe {
output.with_c_str(|output| {
let result = llvm::LLVMRustWriteOutputFile(
pub mod write {
- use back::lto;
- use back::link::{write_output_file, OutputType};
- use back::link::{OutputTypeAssembly, OutputTypeBitcode};
- use back::link::{OutputTypeExe, OutputTypeLlvmAssembly};
- use back::link::{OutputTypeObject};
+ use super::super::lto;
+ use super::{write_output_file, OutputType};
+ use super::{OutputTypeAssembly, OutputTypeBitcode};
+ use super::{OutputTypeExe, OutputTypeLlvmAssembly};
+ use super::{OutputTypeObject};
use driver::driver::{CrateTranslation, OutputFilenames};
use driver::config::NoDebugInfo;
use driver::session::Session;
use driver::config;
- use lib::llvm::llvm;
- use lib::llvm::{ModuleRef, TargetMachineRef, PassManagerRef};
- use lib;
+ use llvm;
+ use llvm::{ModuleRef, TargetMachineRef, PassManagerRef};
use util::common::time;
use syntax::abi;
}
let opt_level = match sess.opts.optimize {
- config::No => lib::llvm::CodeGenLevelNone,
- config::Less => lib::llvm::CodeGenLevelLess,
- config::Default => lib::llvm::CodeGenLevelDefault,
- config::Aggressive => lib::llvm::CodeGenLevelAggressive,
+ config::No => llvm::CodeGenLevelNone,
+ config::Less => llvm::CodeGenLevelLess,
+ config::Default => llvm::CodeGenLevelDefault,
+ config::Aggressive => llvm::CodeGenLevelAggressive,
};
let use_softfp = sess.opts.cg.soft_float;
let fdata_sections = ffunction_sections;
let reloc_model = match sess.opts.cg.relocation_model.as_slice() {
- "pic" => lib::llvm::RelocPIC,
- "static" => lib::llvm::RelocStatic,
- "default" => lib::llvm::RelocDefault,
- "dynamic-no-pic" => lib::llvm::RelocDynamicNoPic,
+ "pic" => llvm::RelocPIC,
+ "static" => llvm::RelocStatic,
+ "default" => llvm::RelocDefault,
+ "dynamic-no-pic" => llvm::RelocDynamicNoPic,
_ => {
sess.err(format!("{} is not a valid relocation mode",
sess.opts
target_feature(sess).with_c_str(|features| {
llvm::LLVMRustCreateTargetMachine(
t, cpu, features,
- lib::llvm::CodeModelDefault,
+ llvm::CodeModelDefault,
reloc_model,
opt_level,
true /* EnableSegstk */,
};
with_codegen(tm, llmod, trans.no_builtins, |cpm| {
write_output_file(sess, tm, cpm, llmod, &path,
- lib::llvm::AssemblyFile);
+ llvm::AssemblyFile);
});
}
OutputTypeObject => {
Some(ref path) => {
with_codegen(tm, llmod, trans.no_builtins, |cpm| {
write_output_file(sess, tm, cpm, llmod, path,
- lib::llvm::ObjectFile);
+ llvm::ObjectFile);
});
}
None => {}
.with_extension("metadata.o");
write_output_file(sess, tm, cpm,
trans.metadata_module, &out,
- lib::llvm::ObjectFile);
+ llvm::ObjectFile);
})
}
});
});
}
- unsafe fn populate_llvm_passes(fpm: lib::llvm::PassManagerRef,
- mpm: lib::llvm::PassManagerRef,
+ unsafe fn populate_llvm_passes(fpm: llvm::PassManagerRef,
+ mpm: llvm::PassManagerRef,
llmod: ModuleRef,
- opt: lib::llvm::CodeGenOptLevel,
+ opt: llvm::CodeGenOptLevel,
no_builtins: bool) {
// Create the PassManagerBuilder for LLVM. We configure it with
// reasonable defaults and prepare it to actually populate the pass
// manager.
let builder = llvm::LLVMPassManagerBuilderCreate();
match opt {
- lib::llvm::CodeGenLevelNone => {
+ llvm::CodeGenLevelNone => {
// Don't add lifetime intrinsics at O0
llvm::LLVMRustAddAlwaysInlinePass(builder, false);
}
- lib::llvm::CodeGenLevelLess => {
+ llvm::CodeGenLevelLess => {
llvm::LLVMRustAddAlwaysInlinePass(builder, true);
}
// numeric values copied from clang
- lib::llvm::CodeGenLevelDefault => {
+ llvm::CodeGenLevelDefault => {
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder,
225);
}
- lib::llvm::CodeGenLevelAggressive => {
+ llvm::CodeGenLevelAggressive => {
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder,
275);
}
* system linkers understand.
*/
-// FIXME (#9639): This needs to handle non-utf8 `out_filestem` values
-pub fn find_crate_id(attrs: &[ast::Attribute], out_filestem: &str) -> CrateId {
- match attr::find_crateid(attrs) {
- None => from_str(out_filestem).unwrap_or_else(|| {
- let mut s = out_filestem.chars().filter(|c| c.is_XID_continue());
- from_str(s.collect::<String>().as_slice())
- .or(from_str("rust-out")).unwrap()
- }),
- Some(s) => s,
+pub fn find_crate_name(sess: Option<&Session>,
+ attrs: &[ast::Attribute],
+ input: &Input) -> String {
+ use syntax::crateid::CrateId;
+
+ let validate = |s: String, span: Option<Span>| {
+ creader::validate_crate_name(sess, s.as_slice(), span);
+ s
+ };
+
+ // Look in attributes 100% of the time to make sure the attribute is marked
+ // as used. After doing this, however, favor crate names from the command
+ // line.
+ let attr_crate_name = attrs.iter().find(|at| at.check_name("crate_name"))
+ .and_then(|at| at.value_str().map(|s| (at, s)));
+
+ match sess {
+ Some(sess) => {
+ match sess.opts.crate_name {
+ Some(ref s) => return validate(s.clone(), None),
+ None => {}
+ }
+ }
+ None => {}
}
-}
-pub fn crate_id_hash(crate_id: &CrateId) -> String {
- // This calculates CMH as defined above. Note that we don't use the path of
- // the crate id in the hash because lookups are only done by (name/vers),
- // not by path.
- let mut s = Sha256::new();
- s.input_str(crate_id.short_name_with_version().as_slice());
- truncated_hash_result(&mut s).as_slice().slice_to(8).to_string()
+ match attr_crate_name {
+ Some((attr, s)) => return validate(s.get().to_string(), Some(attr.span)),
+ None => {}
+ }
+ let crate_id = attrs.iter().find(|at| at.check_name("crate_id"))
+ .and_then(|at| at.value_str().map(|s| (at, s)))
+ .and_then(|(at, s)| {
+ from_str::<CrateId>(s.get()).map(|id| (at, id))
+ });
+ match crate_id {
+ Some((attr, id)) => {
+ match sess {
+ Some(sess) => {
+ sess.span_warn(attr.span, "the #[crate_id] attribute is \
+ deprecated for the \
+ #[crate_name] attribute");
+ }
+ None => {}
+ }
+ return validate(id.name, Some(attr.span))
+ }
+ None => {}
+ }
+ match *input {
+ FileInput(ref path) => {
+ match path.filestem_str() {
+ Some(s) => return validate(s.to_string(), None),
+ None => {}
+ }
+ }
+ _ => {}
+ }
+
+ "rust-out".to_string()
}
-// FIXME (#9639): This needs to handle non-utf8 `out_filestem` values
-pub fn build_link_meta(krate: &ast::Crate, out_filestem: &str) -> LinkMeta {
+pub fn build_link_meta(sess: &Session, krate: &ast::Crate,
+ name: String) -> LinkMeta {
let r = LinkMeta {
- crateid: find_crate_id(krate.attrs.as_slice(), out_filestem),
- crate_hash: Svh::calculate(krate),
+ crate_name: name,
+ crate_hash: Svh::calculate(&sess.opts.cg.metadata, krate),
};
info!("{}", r);
return r;
// to be independent of one another in the crate.
symbol_hasher.reset();
- symbol_hasher.input_str(link_meta.crateid.name.as_slice());
+ symbol_hasher.input_str(link_meta.crate_name.as_slice());
symbol_hasher.input_str("-");
symbol_hasher.input_str(link_meta.crate_hash.as_str());
+ for meta in tcx.sess.crate_metadata.borrow().iter() {
+ symbol_hasher.input_str(meta.as_slice());
+ }
symbol_hasher.input_str("-");
symbol_hasher.input_str(encoder::encoded_ty(tcx, t).as_slice());
// Prefix with 'h' so that it never blends into adjacent digits
}
pub fn mangle<PI: Iterator<PathElem>>(mut path: PI,
- hash: Option<&str>,
- vers: Option<&str>) -> String {
+ hash: Option<&str>) -> String {
// Follow C++ namespace-mangling style, see
// http://en.wikipedia.org/wiki/Name_mangling for more info.
//
Some(s) => push(&mut n, s),
None => {}
}
- match vers {
- Some(s) => push(&mut n, s),
- None => {}
- }
n.push_char('E'); // End name-sequence.
n
}
-pub fn exported_name(path: PathElems, hash: &str, vers: &str) -> String {
- // The version will get mangled to have a leading '_', but it makes more
- // sense to lead with a 'v' b/c this is a version...
- let vers = if vers.len() > 0 && !char::is_XID_start(vers.char_at(0)) {
- format!("v{}", vers)
- } else {
- vers.to_string()
- };
-
- mangle(path, Some(hash), Some(vers.as_slice()))
+pub fn exported_name(path: PathElems, hash: &str) -> String {
+ mangle(path, Some(hash))
}
pub fn mangle_exported_name(ccx: &CrateContext, path: PathElems,
hash.push_char(EXTRA_CHARS.as_bytes()[extra2] as char);
hash.push_char(EXTRA_CHARS.as_bytes()[extra3] as char);
- exported_name(path,
- hash.as_slice(),
- ccx.link_meta.crateid.version_or_default())
+ exported_name(path, hash.as_slice())
}
pub fn mangle_internal_name_by_type_and_seq(ccx: &CrateContext,
t: ty::t,
name: &str) -> String {
- let s = ppaux::ty_to_str(ccx.tcx(), t);
+ let s = ppaux::ty_to_string(ccx.tcx(), t);
let path = [PathName(token::intern(s.as_slice())),
gensym_name(name)];
let hash = get_symbol_hash(ccx, t);
- mangle(ast_map::Values(path.iter()), Some(hash.as_slice()), None)
+ mangle(ast_map::Values(path.iter()), Some(hash.as_slice()))
}
pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> String {
- mangle(path.chain(Some(gensym_name(flav)).move_iter()), None, None)
-}
-
-pub fn output_lib_filename(id: &CrateId) -> String {
- format!("{}-{}-{}", id.name, crate_id_hash(id), id.version_or_default())
+ mangle(path.chain(Some(gensym_name(flav)).move_iter()), None)
}
pub fn get_cc_prog(sess: &Session) -> String {
pub fn link_binary(sess: &Session,
trans: &CrateTranslation,
outputs: &OutputFilenames,
- id: &CrateId) -> Vec<Path> {
+ crate_name: &str) -> Vec<Path> {
let mut out_filenames = Vec::new();
for &crate_type in sess.crate_types.borrow().iter() {
if invalid_output_for_target(sess, crate_type) {
sess.bug(format!("invalid output type `{}` for target os `{}`",
crate_type, sess.targ_cfg.os).as_slice());
}
- let out_file = link_binary_output(sess, trans, crate_type, outputs, id);
+ let out_file = link_binary_output(sess, trans, crate_type, outputs,
+ crate_name);
out_filenames.push(out_file);
}
}
}
-pub fn filename_for_input(sess: &Session, crate_type: config::CrateType,
- id: &CrateId, out_filename: &Path) -> Path {
- let libname = output_lib_filename(id);
+pub fn filename_for_input(sess: &Session,
+ crate_type: config::CrateType,
+ name: &str,
+ out_filename: &Path) -> Path {
+ let libname = format!("{}{}", name, sess.opts.cg.extra_filename);
match crate_type {
config::CrateTypeRlib => {
out_filename.with_filename(format!("lib{}.rlib", libname))
trans: &CrateTranslation,
crate_type: config::CrateType,
outputs: &OutputFilenames,
- id: &CrateId) -> Path {
+ crate_name: &str) -> Path {
let obj_filename = outputs.temp_path(OutputTypeObject);
let out_filename = match outputs.single_output_file {
Some(ref file) => file.clone(),
None => {
let out_filename = outputs.path(OutputTypeExe);
- filename_for_input(sess, crate_type, id, &out_filename)
+ filename_for_input(sess, crate_type, crate_name, &out_filename)
}
};
out_filename
}
+fn archive_search_paths(sess: &Session) -> Vec<Path> {
+ let mut rustpath = filesearch::rust_path();
+ rustpath.push(sess.target_filesearch().get_lib_path());
+ // FIXME: Addl lib search paths are an unordered HashSet?
+ // Shouldn't this search be done in some order?
+ let addl_lib_paths: HashSet<Path> = sess.opts.addl_lib_search_paths.borrow().clone();
+ let mut search: Vec<Path> = addl_lib_paths.move_iter().collect();
+ search.push_all(rustpath.as_slice());
+ return search;
+}
+
// Create an 'rlib'
//
// An rlib in its current incarnation is essentially a renamed .a file. The
trans: Option<&CrateTranslation>, // None == no metadata/bytecode
obj_filename: &Path,
out_filename: &Path) -> Archive<'a> {
- let mut a = Archive::create(sess, out_filename, obj_filename);
+ let handler = &sess.diagnostic().handler;
+ let config = ArchiveConfig {
+ handler: handler,
+ dst: out_filename.clone(),
+ lib_search_paths: archive_search_paths(sess),
+ os: sess.targ_cfg.os,
+ maybe_ar_prog: sess.opts.cg.ar.clone()
+ };
+ let mut a = Archive::create(config, obj_filename);
for &(ref l, kind) in sess.cstore.get_used_libraries().borrow().iter() {
match kind {
if sess.targ_cfg.os == abi::OsMacos {
cmd.args(["-dynamiclib", "-Wl,-dylib"]);
- if !sess.opts.cg.no_rpath {
+ if sess.opts.cg.rpath {
let mut v = Vec::from_slice("-Wl,-install_name,@rpath/".as_bytes());
v.push_all(out_filename.filename().unwrap());
cmd.arg(v.as_slice());
// FIXME (#2397): At some point we want to rpath our guesses as to
// where extern libraries might live, based on the
// addl_lib_search_paths
- if !sess.opts.cg.no_rpath {
- cmd.args(rpath::get_rpath_flags(sess, out_filename).as_slice());
+ if sess.opts.cg.rpath {
+ let sysroot = sess.sysroot();
+ let target_triple = sess.opts.target_triple.as_slice();
+ let get_install_prefix_lib_path = || {
+ let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
+ let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
+ let mut path = Path::new(install_prefix);
+ path.push(&tlib);
+
+ path
+ };
+ let rpath_config = RPathConfig {
+ os: sess.targ_cfg.os,
+ used_crates: sess.cstore.get_used_crates(cstore::RequireDynamic),
+ out_filename: out_filename.clone(),
+ get_install_prefix_lib_path: get_install_prefix_lib_path,
+ realpath: ::util::fs::realpath
+ };
+ cmd.args(rpath::get_rpath_flags(rpath_config).as_slice());
}
// compiler-rt contains implementations of low-level LLVM helpers. This is
sess.abort_if_errors();
}
}
- let mut archive = Archive::open(sess, dst.clone());
+ let handler = &sess.diagnostic().handler;
+ let config = ArchiveConfig {
+ handler: handler,
+ dst: dst.clone(),
+ lib_search_paths: archive_search_paths(sess),
+ os: sess.targ_cfg.os,
+ maybe_ar_prog: sess.opts.cg.ar.clone()
+ };
+ let mut archive = Archive::open(config);
archive.remove_file(format!("{}.o", name).as_slice());
let files = archive.files();
if files.iter().any(|s| s.as_slice().ends_with(".o")) {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use back::archive::ArchiveRO;
-use back::link;
+use super::link;
use driver::session;
use driver::config;
-use lib::llvm::{ModuleRef, TargetMachineRef, llvm, True, False};
+use llvm;
+use llvm::archive_ro::ArchiveRO;
+use llvm::{ModuleRef, TargetMachineRef, True, False};
use metadata::cstore;
use util::common::time;
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use back::target_strs;
-use syntax::abi;
-
-pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
- return target_strs::t {
- module_asm: "".to_string(),
-
- data_layout: match target_os {
- abi::OsMacos => {
- "E-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
-
- abi::OsiOS => {
- "E-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
-
- abi::OsWin32 => {
- "E-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
-
- abi::OsLinux => {
- "E-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
-
- abi::OsAndroid => {
- "E-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
-
- abi::OsFreebsd => {
- "E-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
- },
-
- target_triple: target_triple,
-
- cc_args: Vec::new(),
- };
-}
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use back::target_strs;
-use syntax::abi;
-
-pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
- return target_strs::t {
- module_asm: "".to_string(),
-
- data_layout: match target_os {
- abi::OsMacos => {
- "e-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
-
- abi::OsiOS => {
- "e-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
-
- abi::OsWin32 => {
- "e-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
-
- abi::OsLinux => {
- "e-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
-
- abi::OsAndroid => {
- "e-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
-
- abi::OsFreebsd => {
- "e-p:32:32:32\
- -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
- -f32:32:32-f64:64:64\
- -v64:64:64-v128:64:128\
- -a0:0:64-n32".to_string()
- }
- },
-
- target_triple: target_triple,
-
- cc_args: Vec::new(),
- };
-}
+++ /dev/null
-// Copyright 2012-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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
-use driver::session::Session;
-use metadata::cstore;
-use metadata::filesearch;
-use util::fs;
-
-use std::collections::HashSet;
-use std::os;
-use syntax::abi;
-
-fn not_win32(os: abi::Os) -> bool {
- os != abi::OsWin32
-}
-
-pub fn get_rpath_flags(sess: &Session, out_filename: &Path) -> Vec<String> {
- let os = sess.targ_cfg.os;
-
- // No rpath on windows
- if os == abi::OsWin32 {
- return Vec::new();
- }
-
- let mut flags = Vec::new();
-
- if sess.targ_cfg.os == abi::OsFreebsd {
- flags.push_all(["-Wl,-rpath,/usr/local/lib/gcc46".to_string(),
- "-Wl,-rpath,/usr/local/lib/gcc44".to_string(),
- "-Wl,-z,origin".to_string()]);
- }
-
- debug!("preparing the RPATH!");
-
- let sysroot = sess.sysroot();
- let output = out_filename;
- let libs = sess.cstore.get_used_crates(cstore::RequireDynamic);
- let libs = libs.move_iter().filter_map(|(_, l)| {
- l.map(|p| p.clone())
- }).collect::<Vec<_>>();
-
- let rpaths = get_rpaths(os,
- sysroot,
- output,
- libs.as_slice(),
- sess.opts.target_triple.as_slice());
- flags.push_all(rpaths_to_flags(rpaths.as_slice()).as_slice());
- flags
-}
-
-pub fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
- let mut ret = Vec::new();
- for rpath in rpaths.iter() {
- ret.push(format!("-Wl,-rpath,{}", (*rpath).as_slice()));
- }
- return ret;
-}
-
-fn get_rpaths(os: abi::Os,
- sysroot: &Path,
- output: &Path,
- libs: &[Path],
- target_triple: &str) -> Vec<String> {
- debug!("sysroot: {}", sysroot.display());
- debug!("output: {}", output.display());
- debug!("libs:");
- for libpath in libs.iter() {
- debug!(" {}", libpath.display());
- }
- debug!("target_triple: {}", target_triple);
-
- // Use relative paths to the libraries. Binaries can be moved
- // as long as they maintain the relative relationship to the
- // crates they depend on.
- let rel_rpaths = get_rpaths_relative_to_output(os, output, libs);
-
- // And a final backup rpath to the global library location.
- let fallback_rpaths = vec!(get_install_prefix_rpath(sysroot, target_triple));
-
- fn log_rpaths(desc: &str, rpaths: &[String]) {
- debug!("{} rpaths:", desc);
- for rpath in rpaths.iter() {
- debug!(" {}", *rpath);
- }
- }
-
- log_rpaths("relative", rel_rpaths.as_slice());
- log_rpaths("fallback", fallback_rpaths.as_slice());
-
- let mut rpaths = rel_rpaths;
- rpaths.push_all(fallback_rpaths.as_slice());
-
- // Remove duplicates
- let rpaths = minimize_rpaths(rpaths.as_slice());
- return rpaths;
-}
-
-fn get_rpaths_relative_to_output(os: abi::Os,
- output: &Path,
- libs: &[Path]) -> Vec<String> {
- libs.iter().map(|a| get_rpath_relative_to_output(os, output, a)).collect()
-}
-
-pub fn get_rpath_relative_to_output(os: abi::Os,
- output: &Path,
- lib: &Path)
- -> String {
- use std::os;
-
- assert!(not_win32(os));
-
- // Mac doesn't appear to support $ORIGIN
- let prefix = match os {
- abi::OsAndroid | abi::OsLinux | abi::OsFreebsd
- => "$ORIGIN",
- abi::OsMacos => "@loader_path",
- abi::OsWin32 | abi::OsiOS => unreachable!()
- };
-
- let mut lib = fs::realpath(&os::make_absolute(lib)).unwrap();
- lib.pop();
- let mut output = fs::realpath(&os::make_absolute(output)).unwrap();
- output.pop();
- let relative = lib.path_relative_from(&output);
- let relative = relative.expect("could not create rpath relative to output");
- // FIXME (#9639): This needs to handle non-utf8 paths
- format!("{}/{}",
- prefix,
- relative.as_str().expect("non-utf8 component in path"))
-}
-
-pub fn get_install_prefix_rpath(sysroot: &Path, target_triple: &str) -> String {
- let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
-
- let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
- let mut path = Path::new(install_prefix);
- path.push(&tlib);
- let path = os::make_absolute(&path);
- // FIXME (#9639): This needs to handle non-utf8 paths
- path.as_str().expect("non-utf8 component in rpath").to_string()
-}
-
-pub fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
- let mut set = HashSet::new();
- let mut minimized = Vec::new();
- for rpath in rpaths.iter() {
- if set.insert(rpath.as_slice()) {
- minimized.push(rpath.clone());
- }
- }
- minimized
-}
-
-#[cfg(unix, test)]
-mod test {
- use back::rpath::get_install_prefix_rpath;
- use back::rpath::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output};
- use syntax::abi;
- use metadata::filesearch;
-
- #[test]
- fn test_rpaths_to_flags() {
- let flags = rpaths_to_flags([
- "path1".to_string(),
- "path2".to_string()
- ]);
- assert_eq!(flags,
- vec!("-Wl,-rpath,path1".to_string(),
- "-Wl,-rpath,path2".to_string()));
- }
-
- #[test]
- fn test_prefix_rpath() {
- let sysroot = filesearch::get_or_default_sysroot();
- let res = get_install_prefix_rpath(&sysroot, "triple");
- let mut d = Path::new((option_env!("CFG_PREFIX")).expect("CFG_PREFIX"));
- d.push("lib");
- d.push(filesearch::rustlibdir());
- d.push("triple/lib");
- debug!("test_prefix_path: {} vs. {}",
- res,
- d.display());
- assert!(res.as_bytes().ends_with(d.as_vec()));
- }
-
- #[test]
- fn test_prefix_rpath_abs() {
- let sysroot = filesearch::get_or_default_sysroot();
- let res = get_install_prefix_rpath(&sysroot, "triple");
- assert!(Path::new(res).is_absolute());
- }
-
- #[test]
- fn test_minimize1() {
- let res = minimize_rpaths([
- "rpath1".to_string(),
- "rpath2".to_string(),
- "rpath1".to_string()
- ]);
- assert!(res.as_slice() == [
- "rpath1".to_string(),
- "rpath2".to_string()
- ]);
- }
-
- #[test]
- fn test_minimize2() {
- let res = minimize_rpaths([
- "1a".to_string(),
- "2".to_string(),
- "2".to_string(),
- "1a".to_string(),
- "4a".to_string(),
- "1a".to_string(),
- "2".to_string(),
- "3".to_string(),
- "4a".to_string(),
- "3".to_string()
- ]);
- assert!(res.as_slice() == [
- "1a".to_string(),
- "2".to_string(),
- "4a".to_string(),
- "3".to_string()
- ]);
- }
-
- #[test]
- #[cfg(target_os = "linux")]
- #[cfg(target_os = "android")]
- fn test_rpath_relative() {
- let o = abi::OsLinux;
- let res = get_rpath_relative_to_output(o,
- &Path::new("bin/rustc"), &Path::new("lib/libstd.so"));
- assert_eq!(res.as_slice(), "$ORIGIN/../lib");
- }
-
- #[test]
- #[cfg(target_os = "freebsd")]
- fn test_rpath_relative() {
- let o = abi::OsFreebsd;
- let res = get_rpath_relative_to_output(o,
- &Path::new("bin/rustc"), &Path::new("lib/libstd.so"));
- assert_eq!(res.as_slice(), "$ORIGIN/../lib");
- }
-
- #[test]
- #[cfg(target_os = "macos")]
- fn test_rpath_relative() {
- let o = abi::OsMacos;
- let res = get_rpath_relative_to_output(o,
- &Path::new("bin/rustc"),
- &Path::new("lib/libstd.so"));
- assert_eq!(res.as_slice(), "@loader_path/../lib");
- }
-}
+++ /dev/null
-// Copyright 2012-2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Calculation and management of a Strict Version Hash for crates
-//!
-//! # Today's ABI problem
-//!
-//! In today's implementation of rustc, it is incredibly difficult to achieve
-//! forward binary compatibility without resorting to C-like interfaces. Within
-//! rust code itself, abi details such as symbol names suffer from a variety of
-//! unrelated factors to code changing such as the "def id drift" problem. This
-//! ends up yielding confusing error messages about metadata mismatches and
-//! such.
-//!
-//! The core of this problem is when an upstream dependency changes and
-//! downstream dependents are not recompiled. This causes compile errors because
-//! the upstream crate's metadata has changed but the downstream crates are
-//! still referencing the older crate's metadata.
-//!
-//! This problem exists for many reasons, the primary of which is that rust does
-//! not currently support forwards ABI compatibility (in place upgrades of a
-//! crate).
-//!
-//! # SVH and how it alleviates the problem
-//!
-//! With all of this knowledge on hand, this module contains the implementation
-//! of a notion of a "Strict Version Hash" for a crate. This is essentially a
-//! hash of all contents of a crate which can somehow be exposed to downstream
-//! crates.
-//!
-//! This hash is currently calculated by just hashing the AST, but this is
-//! obviously wrong (doc changes should not result in an incompatible ABI).
-//! Implementation-wise, this is required at this moment in time.
-//!
-//! By encoding this strict version hash into all crate's metadata, stale crates
-//! can be detected immediately and error'd about by rustc itself.
-//!
-//! # Relevant links
-//!
-//! Original issue: https://github.com/rust-lang/rust/issues/10207
-
-use std::fmt;
-use std::hash::Hash;
-use std::hash::sip::SipState;
-use std::iter::range_step;
-use syntax::ast;
-use syntax::visit;
-
-#[deriving(Clone, PartialEq)]
-pub struct Svh {
- hash: String,
-}
-
-impl Svh {
- pub fn new(hash: &str) -> Svh {
- assert!(hash.len() == 16);
- Svh { hash: hash.to_string() }
- }
-
- pub fn as_str<'a>(&'a self) -> &'a str {
- self.hash.as_slice()
- }
-
- pub fn calculate(krate: &ast::Crate) -> Svh {
- // FIXME (#14132): This is better than it used to be, but it still not
- // ideal. We now attempt to hash only the relevant portions of the
- // Crate AST as well as the top-level crate attributes. (However,
- // the hashing of the crate attributes should be double-checked
- // to ensure it is not incorporating implementation artifacts into
- // the hash that are not otherwise visible.)
-
- // FIXME: this should use SHA1, not SipHash. SipHash is not built to
- // avoid collisions.
- let mut state = SipState::new();
-
- {
- let mut visit = svh_visitor::make(&mut state);
- visit::walk_crate(&mut visit, krate, ());
- }
-
- // FIXME (#14132): This hash is still sensitive to e.g. the
- // spans of the crate Attributes and their underlying
- // MetaItems; we should make ContentHashable impl for those
- // types and then use hash_content. But, since all crate
- // attributes should appear near beginning of the file, it is
- // not such a big deal to be sensitive to their spans for now.
- //
- // We hash only the MetaItems instead of the entire Attribute
- // to avoid hashing the AttrId
- for attr in krate.attrs.iter() {
- attr.node.value.hash(&mut state);
- }
-
- let hash = state.result();
- return Svh {
- hash: range_step(0u, 64u, 4u).map(|i| hex(hash >> i)).collect()
- };
-
- fn hex(b: u64) -> char {
- let b = (b & 0xf) as u8;
- let b = match b {
- 0 .. 9 => '0' as u8 + b,
- _ => 'a' as u8 + b - 10,
- };
- b as char
- }
- }
-}
-
-impl fmt::Show for Svh {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.pad(self.as_str())
- }
-}
-
-// FIXME (#14132): Even this SVH computation still has implementation
-// artifacts: namely, the order of item declaration will affect the
-// hash computation, but for many kinds of items the order of
-// declaration should be irrelevant to the ABI.
-
-mod svh_visitor {
- use syntax::ast;
- use syntax::ast::*;
- use syntax::codemap::Span;
- use syntax::parse::token;
- use syntax::print::pprust;
- use syntax::visit;
- use syntax::visit::{Visitor, FnKind};
-
- use std::hash::Hash;
- use std::hash::sip::SipState;
-
- pub struct StrictVersionHashVisitor<'a> {
- pub st: &'a mut SipState,
- }
-
- pub fn make<'a>(st: &'a mut SipState) -> StrictVersionHashVisitor<'a> {
- StrictVersionHashVisitor { st: st }
- }
-
- // To off-load the bulk of the hash-computation on deriving(Hash),
- // we define a set of enums corresponding to the content that our
- // crate visitor will encounter as it traverses the ast.
- //
- // The important invariant is that all of the Saw*Component enums
- // do not carry any Spans, Names, or Idents.
- //
- // Not carrying any Names/Idents is the important fix for problem
- // noted on PR #13948: using the ident.name as the basis for a
- // hash leads to unstable SVH, because ident.name is just an index
- // into intern table (i.e. essentially a random address), not
- // computed from the name content.
- //
- // With the below enums, the SVH computation is not sensitive to
- // artifacts of how rustc was invoked nor of how the source code
- // was laid out. (Or at least it is *less* sensitive.)
-
- // This enum represents the different potential bits of code the
- // visitor could encounter that could affect the ABI for the crate,
- // and assigns each a distinct tag to feed into the hash computation.
- #[deriving(Hash)]
- enum SawAbiComponent<'a> {
-
- // FIXME (#14132): should we include (some function of)
- // ident.ctxt as well?
- SawIdent(token::InternedString),
- SawStructDef(token::InternedString),
-
- SawLifetimeRef(token::InternedString),
- SawLifetimeDecl(token::InternedString),
-
- SawMod,
- SawViewItem,
- SawForeignItem,
- SawItem,
- SawDecl,
- SawTy,
- SawGenerics,
- SawFn,
- SawTyMethod,
- SawTraitMethod,
- SawStructField,
- SawVariant,
- SawExplicitSelf,
- SawPath,
- SawOptLifetimeRef,
- SawBlock,
- SawPat,
- SawLocal,
- SawArm,
- SawExpr(SawExprComponent<'a>),
- SawStmt(SawStmtComponent),
- }
-
- /// SawExprComponent carries all of the information that we want
- /// to include in the hash that *won't* be covered by the
- /// subsequent recursive traversal of the expression's
- /// substructure by the visitor.
- ///
- /// We know every Expr_ variant is covered by a variant because
- /// `fn saw_expr` maps each to some case below. Ensuring that
- /// each variant carries an appropriate payload has to be verified
- /// by hand.
- ///
- /// (However, getting that *exactly* right is not so important
- /// because the SVH is just a developer convenience; there is no
- /// guarantee of collision-freedom, hash collisions are just
- /// (hopefully) unlikely.)
- #[deriving(Hash)]
- pub enum SawExprComponent<'a> {
-
- SawExprLoop(Option<token::InternedString>),
- SawExprField(token::InternedString),
- SawExprBreak(Option<token::InternedString>),
- SawExprAgain(Option<token::InternedString>),
-
- SawExprVstore,
- SawExprBox,
- SawExprVec,
- SawExprCall,
- SawExprMethodCall,
- SawExprTup,
- SawExprBinary(ast::BinOp),
- SawExprUnary(ast::UnOp),
- SawExprLit(ast::Lit_),
- SawExprCast,
- SawExprIf,
- SawExprWhile,
- SawExprMatch,
- SawExprFnBlock,
- SawExprProc,
- SawExprBlock,
- SawExprAssign,
- SawExprAssignOp(ast::BinOp),
- SawExprIndex,
- SawExprPath,
- SawExprAddrOf(ast::Mutability),
- SawExprRet,
- SawExprInlineAsm(&'a ast::InlineAsm),
- SawExprStruct,
- SawExprRepeat,
- SawExprParen,
- }
-
- fn saw_expr<'a>(node: &'a Expr_) -> SawExprComponent<'a> {
- match *node {
- ExprVstore(..) => SawExprVstore,
- ExprBox(..) => SawExprBox,
- ExprVec(..) => SawExprVec,
- ExprCall(..) => SawExprCall,
- ExprMethodCall(..) => SawExprMethodCall,
- ExprTup(..) => SawExprTup,
- ExprBinary(op, _, _) => SawExprBinary(op),
- ExprUnary(op, _) => SawExprUnary(op),
- ExprLit(lit) => SawExprLit(lit.node.clone()),
- ExprCast(..) => SawExprCast,
- ExprIf(..) => SawExprIf,
- ExprWhile(..) => SawExprWhile,
- ExprLoop(_, id) => SawExprLoop(id.map(content)),
- ExprMatch(..) => SawExprMatch,
- ExprFnBlock(..) => SawExprFnBlock,
- ExprProc(..) => SawExprProc,
- ExprBlock(..) => SawExprBlock,
- ExprAssign(..) => SawExprAssign,
- ExprAssignOp(op, _, _) => SawExprAssignOp(op),
- ExprField(_, id, _) => SawExprField(content(id.node)),
- ExprIndex(..) => SawExprIndex,
- ExprPath(..) => SawExprPath,
- ExprAddrOf(m, _) => SawExprAddrOf(m),
- ExprBreak(id) => SawExprBreak(id.map(content)),
- ExprAgain(id) => SawExprAgain(id.map(content)),
- ExprRet(..) => SawExprRet,
- ExprInlineAsm(ref asm) => SawExprInlineAsm(asm),
- ExprStruct(..) => SawExprStruct,
- ExprRepeat(..) => SawExprRepeat,
- ExprParen(..) => SawExprParen,
-
- // just syntactic artifacts, expanded away by time of SVH.
- ExprForLoop(..) => unreachable!(),
- ExprMac(..) => unreachable!(),
- }
- }
-
- /// SawStmtComponent is analogous to SawExprComponent, but for statements.
- #[deriving(Hash)]
- pub enum SawStmtComponent {
- SawStmtDecl,
- SawStmtExpr,
- SawStmtSemi,
- }
-
- fn saw_stmt(node: &Stmt_) -> SawStmtComponent {
- match *node {
- StmtDecl(..) => SawStmtDecl,
- StmtExpr(..) => SawStmtExpr,
- StmtSemi(..) => SawStmtSemi,
- StmtMac(..) => unreachable!(),
- }
- }
-
- // Ad-hoc overloading between Ident and Name to their intern table lookups.
- trait InternKey { fn get_content(self) -> token::InternedString; }
- impl InternKey for Ident {
- fn get_content(self) -> token::InternedString { token::get_ident(self) }
- }
- impl InternKey for Name {
- fn get_content(self) -> token::InternedString { token::get_name(self) }
- }
- fn content<K:InternKey>(k: K) -> token::InternedString { k.get_content() }
-
- // local short-hand eases writing signatures of syntax::visit mod.
- type E = ();
-
- impl<'a> Visitor<E> for StrictVersionHashVisitor<'a> {
-
- fn visit_mac(&mut self, macro: &Mac, e: E) {
- // macro invocations, namely macro_rules definitions,
- // *can* appear as items, even in the expanded crate AST.
-
- if macro_name(macro).get() == "macro_rules" {
- // Pretty-printing definition to a string strips out
- // surface artifacts (currently), such as the span
- // information, yielding a content-based hash.
-
- // FIXME (#14132): building temporary string is
- // expensive; a direct content-based hash on token
- // trees might be faster. Implementing this is far
- // easier in short term.
- let macro_defn_as_string =
- pprust::to_str(|pp_state| pp_state.print_mac(macro));
- macro_defn_as_string.hash(self.st);
- } else {
- // It is not possible to observe any kind of macro
- // invocation at this stage except `macro_rules!`.
- fail!("reached macro somehow: {}",
- pprust::to_str(|pp_state| pp_state.print_mac(macro)));
- }
-
- visit::walk_mac(self, macro, e);
-
- fn macro_name(macro: &Mac) -> token::InternedString {
- match ¯o.node {
- &MacInvocTT(ref path, ref _tts, ref _stx_ctxt) => {
- let s = path.segments.as_slice();
- assert_eq!(s.len(), 1);
- content(s[0].identifier)
- }
- }
- }
- }
-
- fn visit_struct_def(&mut self, s: &StructDef, ident: Ident,
- g: &Generics, _: NodeId, e: E) {
- SawStructDef(content(ident)).hash(self.st);
- visit::walk_generics(self, g, e.clone());
- visit::walk_struct_def(self, s, e)
- }
-
- fn visit_variant(&mut self, v: &Variant, g: &Generics, e: E) {
- SawVariant.hash(self.st);
- // walk_variant does not call walk_generics, so do it here.
- visit::walk_generics(self, g, e.clone());
- visit::walk_variant(self, v, g, e)
- }
-
- fn visit_opt_lifetime_ref(&mut self, _: Span, l: &Option<Lifetime>, env: E) {
- SawOptLifetimeRef.hash(self.st);
- // (This is a strange method in the visitor trait, in that
- // it does not expose a walk function to do the subroutine
- // calls.)
- match *l {
- Some(ref l) => self.visit_lifetime_ref(l, env),
- None => ()
- }
- }
-
- // All of the remaining methods just record (in the hash
- // SipState) that the visitor saw that particular variant
- // (with its payload), and continue walking as the default
- // visitor would.
- //
- // Some of the implementations have some notes as to how one
- // might try to make their SVH computation less discerning
- // (e.g. by incorporating reachability analysis). But
- // currently all of their implementations are uniform and
- // uninteresting.
- //
- // (If you edit a method such that it deviates from the
- // pattern, please move that method up above this comment.)
-
- fn visit_ident(&mut self, _: Span, ident: Ident, _: E) {
- SawIdent(content(ident)).hash(self.st);
- }
-
- fn visit_lifetime_ref(&mut self, l: &Lifetime, _: E) {
- SawLifetimeRef(content(l.name)).hash(self.st);
- }
-
- fn visit_lifetime_decl(&mut self, l: &Lifetime, _: E) {
- SawLifetimeDecl(content(l.name)).hash(self.st);
- }
-
- // We do recursively walk the bodies of functions/methods
- // (rather than omitting their bodies from the hash) since
- // monomorphization and cross-crate inlining generally implies
- // that a change to a crate body will require downstream
- // crates to be recompiled.
- fn visit_expr(&mut self, ex: &Expr, e: E) {
- SawExpr(saw_expr(&ex.node)).hash(self.st); visit::walk_expr(self, ex, e)
- }
-
- fn visit_stmt(&mut self, s: &Stmt, e: E) {
- SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s, e)
- }
-
- fn visit_view_item(&mut self, i: &ViewItem, e: E) {
- // Two kinds of view items can affect the ABI for a crate:
- // exported `pub use` view items (since that may expose
- // items that downstream crates can call), and `use
- // foo::Trait`, since changing that may affect method
- // resolution.
- //
- // The simplest approach to handling both of the above is
- // just to adopt the same simple-minded (fine-grained)
- // hash that I am deploying elsewhere here.
- SawViewItem.hash(self.st); visit::walk_view_item(self, i, e)
- }
-
- fn visit_foreign_item(&mut self, i: &ForeignItem, e: E) {
- // FIXME (#14132) ideally we would incorporate privacy (or
- // perhaps reachability) somewhere here, so foreign items
- // that do not leak into downstream crates would not be
- // part of the ABI.
- SawForeignItem.hash(self.st); visit::walk_foreign_item(self, i, e)
- }
-
- fn visit_item(&mut self, i: &Item, e: E) {
- // FIXME (#14132) ideally would incorporate reachability
- // analysis somewhere here, so items that never leak into
- // downstream crates (e.g. via monomorphisation or
- // inlining) would not be part of the ABI.
- SawItem.hash(self.st); visit::walk_item(self, i, e)
- }
-
- fn visit_mod(&mut self, m: &Mod, _s: Span, _n: NodeId, e: E) {
- SawMod.hash(self.st); visit::walk_mod(self, m, e)
- }
-
- fn visit_decl(&mut self, d: &Decl, e: E) {
- SawDecl.hash(self.st); visit::walk_decl(self, d, e)
- }
-
- fn visit_ty(&mut self, t: &Ty, e: E) {
- SawTy.hash(self.st); visit::walk_ty(self, t, e)
- }
-
- fn visit_generics(&mut self, g: &Generics, e: E) {
- SawGenerics.hash(self.st); visit::walk_generics(self, g, e)
- }
-
- fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId, e: E) {
- SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s, e)
- }
-
- fn visit_ty_method(&mut self, t: &TypeMethod, e: E) {
- SawTyMethod.hash(self.st); visit::walk_ty_method(self, t, e)
- }
-
- fn visit_trait_method(&mut self, t: &TraitMethod, e: E) {
- SawTraitMethod.hash(self.st); visit::walk_trait_method(self, t, e)
- }
-
- fn visit_struct_field(&mut self, s: &StructField, e: E) {
- SawStructField.hash(self.st); visit::walk_struct_field(self, s, e)
- }
-
- fn visit_explicit_self(&mut self, es: &ExplicitSelf, e: E) {
- SawExplicitSelf.hash(self.st); visit::walk_explicit_self(self, es, e)
- }
-
- fn visit_path(&mut self, path: &Path, _: ast::NodeId, e: E) {
- SawPath.hash(self.st); visit::walk_path(self, path, e)
- }
-
- fn visit_block(&mut self, b: &Block, e: E) {
- SawBlock.hash(self.st); visit::walk_block(self, b, e)
- }
-
- fn visit_pat(&mut self, p: &Pat, e: E) {
- SawPat.hash(self.st); visit::walk_pat(self, p, e)
- }
-
- fn visit_local(&mut self, l: &Local, e: E) {
- SawLocal.hash(self.st); visit::walk_local(self, l, e)
- }
-
- fn visit_arm(&mut self, a: &Arm, e: E) {
- SawArm.hash(self.st); visit::walk_arm(self, a, e)
- }
- }
-}
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(non_camel_case_types)]
-
-pub struct t {
- pub module_asm: String,
- pub data_layout: String,
- pub target_triple: String,
- pub cc_args: Vec<String> ,
-}
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
-use back::target_strs;
-use syntax::abi;
-
-pub fn get_target_strs(target_triple: String, target_os: abi::Os)
- -> target_strs::t {
- return target_strs::t {
- module_asm: "".to_string(),
-
- data_layout: match target_os {
- abi::OsMacos => {
- "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16\
- -i32:32:32-i64:32:64\
- -f32:32:32-f64:32:64-v64:64:64\
- -v128:128:128-a0:0:64-f80:128:128\
- -n8:16:32".to_string()
- }
-
- abi::OsiOS => {
- "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16\
- -i32:32:32-i64:32:64\
- -f32:32:32-f64:32:64-v64:64:64\
- -v128:128:128-a0:0:64-f80:128:128\
- -n8:16:32".to_string()
- }
-
- abi::OsWin32 => {
- "e-p:32:32-f64:64:64-i64:64:64-f80:32:32-n8:16:32".to_string()
- }
-
- abi::OsLinux => {
- "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string()
- }
- abi::OsAndroid => {
- "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string()
- }
-
- abi::OsFreebsd => {
- "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string()
- }
- },
-
- target_triple: target_triple,
-
- cc_args: vec!("-m32".to_string()),
- };
-}
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-
-use back::target_strs;
-use syntax::abi;
-
-pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
- return target_strs::t {
- module_asm: "".to_string(),
-
- data_layout: match target_os {
- abi::OsMacos => {
- "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
- f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
- s0:64:64-f80:128:128-n8:16:32:64".to_string()
- }
-
- abi::OsiOS => {
- "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
- f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
- s0:64:64-f80:128:128-n8:16:32:64".to_string()
- }
-
- abi::OsWin32 => {
- // FIXME: Test this. Copied from linux (#2398)
- "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
- f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
- s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
- }
-
- abi::OsLinux => {
- "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
- f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
- s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
- }
- abi::OsAndroid => {
- "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
- f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
- s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
- }
-
- abi::OsFreebsd => {
- "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
- f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
- s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
- }
- },
-
- target_triple: target_triple,
-
- cc_args: vec!("-m64".to_string()),
- };
-}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+register_diagnostic!(E0001, r##"
+ This error suggests that the expression arm corresponding to the noted pattern
+ will never be reached as for all possible values of the expression being matched,
+ one of the preceeding patterns will match.
+
+ This means that perhaps some of the preceeding patterns are too general, this
+ one is too specific or the ordering is incorrect.
+"##)
//! Contains infrastructure for configuring the compiler, including parsing
//! command line options.
-use driver::early_error;
+use driver::{early_error, early_warn};
use driver::driver;
use driver::session::Session;
use syntax::parse;
use syntax::parse::token::InternedString;
-use std::collections::HashSet;
+use std::collections::{HashSet, HashMap};
use getopts::{optopt, optmulti, optflag, optflagopt};
use getopts;
-use lib::llvm::llvm;
use std::cell::{RefCell};
use std::fmt;
+use llvm;
pub struct Config {
pub os: abi::Os,
pub debugging_opts: u64,
/// Whether to write dependency files. It's (enabled, optional filename).
pub write_dependency_info: (bool, Option<Path>),
- /// Crate id-related things to maybe print. It's (crate_id, crate_name, crate_file_name).
- pub print_metas: (bool, bool, bool),
+ /// Crate id-related things to maybe print. It's (crate_name, crate_file_name).
+ pub print_metas: (bool, bool),
pub cg: CodegenOptions,
pub color: ColorConfig,
+ pub externs: HashMap<String, Vec<String>>,
+ pub crate_name: Option<String>,
}
/// Some reasonable defaults
no_analysis: false,
debugging_opts: 0,
write_dependency_info: (false, None),
- print_metas: (false, false, false),
+ print_metas: (false, false),
cg: basic_codegen_options(),
color: Auto,
+ externs: HashMap::new(),
+ crate_name: None,
}
}
AST_JSON,
AST_JSON_NOEXPAND,
LS,
- SAVE_ANALYSIS
+ SAVE_ANALYSIS,
+ FLOWGRAPH_PRINT_LOANS,
+ FLOWGRAPH_PRINT_MOVES,
+ FLOWGRAPH_PRINT_ASSIGNS,
+ FLOWGRAPH_PRINT_ALL
]
0
)
("ast-json-noexpand", "Print the pre-expansion AST as JSON and halt", AST_JSON_NOEXPAND),
("ls", "List the symbols defined by a library crate", LS),
("save-analysis", "Write syntax and type analysis information \
- in addition to normal output", SAVE_ANALYSIS))
+ in addition to normal output", SAVE_ANALYSIS),
+ ("flowgraph-print-loans", "Include loan analysis data in \
+ --pretty flowgraph output", FLOWGRAPH_PRINT_LOANS),
+ ("flowgraph-print-moves", "Include move analysis data in \
+ --pretty flowgraph output", FLOWGRAPH_PRINT_MOVES),
+ ("flowgraph-print-assigns", "Include assignment analysis data in \
+ --pretty flowgraph output", FLOWGRAPH_PRINT_ASSIGNS),
+ ("flowgraph-print-all", "Include all dataflow analysis data in \
+ --pretty flowgraph output", FLOWGRAPH_PRINT_ALL))
}
/// Declare a macro that will define all CodegenOptions fields and parsers all
"a list of arguments to pass to llvm (space separated)"),
save_temps: bool = (false, parse_bool,
"save all temporary output files during compilation"),
- no_rpath: bool = (false, parse_bool,
- "disables setting the rpath in libs/exes"),
+ rpath: bool = (false, parse_bool,
+ "set rpath values in libs/exes"),
no_prepopulate_passes: bool = (false, parse_bool,
"don't pre-populate the pass manager with a list of passes"),
no_vectorize_loops: bool = (false, parse_bool,
"use an external assembler rather than LLVM's integrated one"),
relocation_model: String = ("pic".to_string(), parse_string,
"choose the relocation model to use (llc -relocation-model for details)"),
+ metadata: Vec<String> = (Vec::new(), parse_list,
+ "metadata to mangle symbol names with"),
+ extra_filename: String = ("".to_string(), parse_string,
+ "extra data to put in each output filename"),
)
pub fn build_codegen_options(matches: &getopts::Matches) -> CodegenOptions
}
None
}
-static os_names : &'static [(&'static str, abi::Os)] = &'static [
+static os_names : &'static [(&'static str, abi::Os)] = &[
("mingw32", abi::OsWin32),
("win32", abi::OsWin32),
("darwin", abi::OsMacos),
}
None
}
-static architecture_abis : &'static [(&'static str, abi::Architecture)] = &'static [
+static architecture_abis : &'static [(&'static str, abi::Architecture)] = &[
("i386", abi::X86),
("i486", abi::X86),
("i586", abi::X86),
"[bin|lib|rlib|dylib|staticlib]"),
optmulti("", "emit", "Comma separated list of types of output for the compiler to emit",
"[asm|bc|ir|obj|link]"),
- optflag("", "crate-id", "Output the crate id and exit"),
- optflag("", "crate-name", "Output the crate name and exit"),
- optflag("", "crate-file-name", "Output the file(s) that would be written if compilation \
+ optopt("", "crate-name", "Specify the name of the crate being built",
+ "NAME"),
+ optflag("", "print-crate-name", "Output the crate name and exit"),
+ optflag("", "print-file-name", "Output the file(s) that would be written if compilation \
continued and exit"),
+ optflag("", "crate-file-name", "deprecated in favor of --print-file-name"),
optflag("g", "", "Equivalent to --debuginfo=2"),
optopt("", "debuginfo", "Emit DWARF debug info to the objects created:
0 = no debug info,
optopt("", "opt-level", "Optimize with possible levels 0-3", "LEVEL"),
optopt( "", "out-dir", "Write output to compiler-chosen filename in <dir>", "DIR"),
optflag("", "parse-only", "Parse only; do not compile, assemble, or link"),
+ optopt("", "explain", "Provide a detailed explanation of an error message", "OPT"),
optflagopt("", "pretty",
"Pretty-print the input instead of compiling;
valid types are: `normal` (un-annotated source),
optopt("", "color", "Configure coloring of output:
auto = colorize, if output goes to a tty (default);
always = always colorize output;
- never = never colorize output", "auto|always|never")
+ never = never colorize output", "auto|always|never"),
+ optmulti("", "extern", "Specify where an external rust library is located",
+ "PATH"),
)
}
matches.opt_str("dep-info")
.map(|p| Path::new(p)));
- let print_metas = (matches.opt_present("crate-id"),
- matches.opt_present("crate-name"),
+ let print_metas = (matches.opt_present("print-crate-name"),
+ matches.opt_present("print-file-name") ||
matches.opt_present("crate-file-name"));
+ if matches.opt_present("crate-file-name") {
+ early_warn("the --crate-file-name argument has been renamed to \
+ --print-file-name");
+ }
let cg = build_codegen_options(matches);
let color = match matches.opt_str("color").as_ref().map(|s| s.as_slice()) {
}
};
+ let mut externs = HashMap::new();
+ for arg in matches.opt_strs("extern").iter() {
+ let mut parts = arg.as_slice().splitn('=', 1);
+ let name = match parts.next() {
+ Some(s) => s,
+ None => early_error("--extern value must not be empty"),
+ };
+ let location = match parts.next() {
+ Some(s) => s,
+ None => early_error("--extern value must be of the format `foo=bar`"),
+ };
+ let locs = externs.find_or_insert(name.to_string(), Vec::new());
+ locs.push(location.to_string());
+ }
+
+ let crate_name = matches.opt_str("crate-name");
+
Options {
crate_types: crate_types,
gc: gc,
write_dependency_info: write_dependency_info,
print_metas: print_metas,
cg: cg,
- color: color
+ color: color,
+ externs: externs,
+ crate_name: crate_name,
}
}
use getopts::getopts;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
+ use syntax::diagnostics;
// When the user supplies --test we should implicitly supply --cfg test
#[test]
Ok(m) => m,
Err(f) => fail!("test_switch_implies_cfg_test: {}", f)
};
+ let registry = diagnostics::registry::Registry::new([]);
let sessopts = build_session_options(matches);
- let sess = build_session(sessopts, None);
+ let sess = build_session(sessopts, None, registry);
let cfg = build_configuration(&sess);
assert!((attr::contains_name(cfg.as_slice(), "test")));
}
fail!("test_switch_implies_cfg_test_unless_cfg_test: {}", f)
}
};
+ let registry = diagnostics::registry::Registry::new([]);
let sessopts = build_session_options(matches);
- let sess = build_session(sessopts, None);
+ let sess = build_session(sessopts, None, registry);
let cfg = build_configuration(&sess);
let mut test_items = cfg.iter().filter(|m| m.name().equiv(&("test")));
assert!(test_items.next().is_some());
use driver::{PpmFlowGraph, PpmExpanded, PpmExpandedIdentified, PpmTyped};
use driver::{PpmIdentified};
use front;
-use lib::llvm::{ContextRef, ModuleRef};
+use lint;
+use llvm::{ContextRef, ModuleRef};
use metadata::common::LinkMeta;
use metadata::creader;
+use middle::borrowck::{FnPartsWithCFG};
+use middle::borrowck;
+use borrowck_dot = middle::borrowck::graphviz;
use middle::cfg;
use middle::cfg::graphviz::LabelledCFG;
use middle::{trans, freevars, stability, kind, ty, typeck, reachable};
use plugin::load::Plugins;
use plugin::registry::Registry;
use plugin;
-use lint;
+
use util::common::time;
use util::ppaux;
use util::nodemap::{NodeSet};
use std::io::fs;
use std::io::MemReader;
use syntax::ast;
+use syntax::ast_map::blocks;
use syntax::attr;
use syntax::attr::{AttrMetaMethods};
-use syntax::crateid::CrateId;
+use syntax::diagnostics;
use syntax::parse;
use syntax::parse::token;
use syntax::print::{pp, pprust};
// large chunks of memory alive and we want to free them as soon as
// possible to keep the peak memory usage low
let (outputs, trans, sess) = {
- let (outputs, expanded_crate, ast_map) = {
+ let (outputs, expanded_crate, ast_map, id) = {
let krate = phase_1_parse_input(&sess, cfg, input);
if stop_after_phase_1(&sess) { return; }
let outputs = build_output_filenames(input,
output,
krate.attrs.as_slice(),
&sess);
- let id = link::find_crate_id(krate.attrs.as_slice(),
- outputs.out_filestem.as_slice());
+ let id = link::find_crate_name(Some(&sess), krate.attrs.as_slice(),
+ input);
let (expanded_crate, ast_map)
- = match phase_2_configure_and_expand(&sess, krate, &id) {
+ = match phase_2_configure_and_expand(&sess, krate, id.as_slice()) {
None => return,
Some(p) => p,
};
- (outputs, expanded_crate, ast_map)
+ (outputs, expanded_crate, ast_map, id)
};
- write_out_deps(&sess, input, &outputs, &expanded_crate);
+ write_out_deps(&sess, input, &outputs, id.as_slice());
if stop_after_phase_2(&sess) { return; }
- let analysis = phase_3_run_analysis_passes(sess, &expanded_crate, ast_map);
+ let analysis = phase_3_run_analysis_passes(sess, &expanded_crate,
+ ast_map, id);
phase_save_analysis(&analysis.ty_cx.sess, &expanded_crate, &analysis, outdir);
if stop_after_phase_3(&analysis.ty_cx.sess) { return; }
- let (tcx, trans) = phase_4_translate_to_llvm(expanded_crate,
- analysis, &outputs);
+ let (tcx, trans) = phase_4_translate_to_llvm(expanded_crate, analysis);
// Discard interned strings as they are no longer required.
token::get_ident_interner().clear();
/// Returns `None` if we're aborting after handling -W help.
pub fn phase_2_configure_and_expand(sess: &Session,
mut krate: ast::Crate,
- crate_id: &CrateId)
+ crate_name: &str)
-> Option<(ast::Crate, syntax::ast_map::Map)> {
let time_passes = sess.time_passes();
- *sess.crate_types.borrow_mut() = collect_crate_types(sess, krate.attrs.as_slice());
+ *sess.crate_types.borrow_mut() =
+ collect_crate_types(sess, krate.attrs.as_slice());
+ *sess.crate_metadata.borrow_mut() =
+ collect_crate_metadata(sess, krate.attrs.as_slice());
time(time_passes, "gated feature checking", (), |_|
front::feature_gate::check_crate(sess, &krate));
let mut registry = Registry::new(&krate);
time(time_passes, "plugin registration", (), |_| {
+ if sess.features.rustc_diagnostic_macros.get() {
+ registry.register_macro("__diagnostic_used",
+ diagnostics::plugin::expand_diagnostic_used);
+ registry.register_macro("__register_diagnostic",
+ diagnostics::plugin::expand_register_diagnostic);
+ registry.register_macro("__build_diagnostic_array",
+ diagnostics::plugin::expand_build_diagnostic_array);
+ }
+
for ®istrar in registrars.iter() {
registrar(&mut registry);
}
}
let cfg = syntax::ext::expand::ExpansionConfig {
deriving_hash_type_parameter: sess.features.default_type_params.get(),
- crate_id: crate_id.clone(),
+ crate_name: crate_name.to_string(),
};
syntax::ext::expand::expand_crate(&sess.parse_sess,
cfg,
}
);
+ // JBC: make CFG processing part of expansion to avoid this problem:
+
// strip again, in case expansion added anything with a #[cfg].
krate = time(time_passes, "configuration 2", krate, |krate|
front::config::strip_unconfigured_items(krate));
krate.encode(&mut json).unwrap();
}
+ time(time_passes, "checking that all macro invocations are gone", &krate, |krate|
+ syntax::ext::expand::check_for_macros(&sess.parse_sess, krate));
+
Some((krate, map))
}
pub public_items: middle::privacy::PublicItems,
pub ty_cx: ty::ctxt,
pub reachable: NodeSet,
+ pub name: String,
}
+
/// Run the resolution, typechecking, region checking and other
/// miscellaneous analysis passes on the crate. Return various
/// structures carrying the results of the analysis.
pub fn phase_3_run_analysis_passes(sess: Session,
krate: &ast::Crate,
- ast_map: syntax::ast_map::Map) -> CrateAnalysis {
-
+ ast_map: syntax::ast_map::Map,
+ name: String) -> CrateAnalysis {
let time_passes = sess.time_passes();
time(time_passes, "external crate/lib resolution", (), |_|
exported_items: exported_items,
public_items: public_items,
reachable: reachable_map,
+ name: name,
}
}
/// Run the translation phase to LLVM, after which the AST and analysis can
/// be discarded.
pub fn phase_4_translate_to_llvm(krate: ast::Crate,
- analysis: CrateAnalysis,
- outputs: &OutputFilenames) -> (ty::ctxt, CrateTranslation) {
+ analysis: CrateAnalysis) -> (ty::ctxt, CrateTranslation) {
let time_passes = analysis.ty_cx.sess.time_passes();
time(time_passes, "resolving dependency formats", (), |_|
// Option dance to work around the lack of stack once closures.
time(time_passes, "translation", (krate, analysis), |(krate, analysis)|
- trans::base::trans_crate(krate, analysis, outputs))
+ trans::base::trans_crate(krate, analysis))
}
/// Run LLVM itself, producing a bitcode file, assembly file or object file
link::link_binary(sess,
trans,
outputs,
- &trans.link.crateid));
+ trans.link.crate_name.as_slice()));
}
pub fn stop_after_phase_3(sess: &Session) -> bool {
fn write_out_deps(sess: &Session,
input: &Input,
outputs: &OutputFilenames,
- krate: &ast::Crate) {
- let id = link::find_crate_id(krate.attrs.as_slice(),
- outputs.out_filestem.as_slice());
+ id: &str) {
let mut out_filenames = Vec::new();
for output_type in sess.opts.output_types.iter() {
match *output_type {
link::OutputTypeExe => {
for output in sess.crate_types.borrow().iter() {
- let p = link::filename_for_input(sess, *output, &id, &file);
+ let p = link::filename_for_input(sess, *output,
+ id, &file);
out_filenames.push(p);
}
}
match node {
pprust::NodeItem(item) => {
try!(pp::space(&mut s.s));
- s.synth_comment(item.id.to_str())
+ s.synth_comment(item.id.to_string())
}
pprust::NodeBlock(blk) => {
try!(pp::space(&mut s.s));
}
pprust::NodeExpr(expr) => {
try!(pp::space(&mut s.s));
- try!(s.synth_comment(expr.id.to_str()));
+ try!(s.synth_comment(expr.id.to_string()));
s.pclose()
}
pprust::NodePat(pat) => {
try!(pp::word(&mut s.s, "as"));
try!(pp::space(&mut s.s));
try!(pp::word(&mut s.s,
- ppaux::ty_to_str(
+ ppaux::ty_to_string(
tcx,
ty::expr_ty(tcx, expr)).as_slice()));
s.pclose()
}
}
+fn gather_flowgraph_variants(sess: &Session) -> Vec<borrowck_dot::Variant> {
+ let print_loans = config::FLOWGRAPH_PRINT_LOANS;
+ let print_moves = config::FLOWGRAPH_PRINT_MOVES;
+ let print_assigns = config::FLOWGRAPH_PRINT_ASSIGNS;
+ let print_all = config::FLOWGRAPH_PRINT_ALL;
+ let opt = |print_which| sess.debugging_opt(print_which);
+ let mut variants = Vec::new();
+ if opt(print_all) || opt(print_loans) {
+ variants.push(borrowck_dot::Loans);
+ }
+ if opt(print_all) || opt(print_moves) {
+ variants.push(borrowck_dot::Moves);
+ }
+ if opt(print_all) || opt(print_assigns) {
+ variants.push(borrowck_dot::Assigns);
+ }
+ variants
+}
+
pub fn pretty_print_input(sess: Session,
cfg: ast::CrateConfig,
input: &Input,
ppm: PpMode,
ofile: Option<Path>) {
let krate = phase_1_parse_input(&sess, cfg, input);
- let id = link::find_crate_id(krate.attrs.as_slice(),
- input.filestem().as_slice());
+ let id = link::find_crate_name(Some(&sess), krate.attrs.as_slice(), input);
let (krate, ast_map, is_expanded) = match ppm {
PpmExpanded | PpmExpandedIdentified | PpmTyped | PpmFlowGraph(_) => {
let (krate, ast_map)
- = match phase_2_configure_and_expand(&sess, krate, &id) {
+ = match phase_2_configure_and_expand(&sess, krate,
+ id.as_slice()) {
None => return,
Some(p) => p,
};
}
PpmTyped => {
let ast_map = ast_map.expect("--pretty=typed missing ast_map");
- let analysis = phase_3_run_analysis_passes(sess, &krate, ast_map);
+ let analysis = phase_3_run_analysis_passes(sess, &krate, ast_map, id);
let annotation = TypedAnnotation {
analysis: analysis
};
sess.fatal(format!("--pretty flowgraph couldn't find id: {}",
nodeid).as_slice())
});
- let block = match node {
- syntax::ast_map::NodeBlock(block) => block,
- _ => {
- let message = format!("--pretty=flowgraph needs block, got {:?}",
+ let code = blocks::Code::from_node(node);
+ match code {
+ Some(code) => {
+ let variants = gather_flowgraph_variants(&sess);
+ let analysis = phase_3_run_analysis_passes(sess, &krate,
+ ast_map, id);
+ print_flowgraph(variants, analysis, code, out)
+ }
+ None => {
+ let message = format!("--pretty=flowgraph needs \
+ block, fn, or method; got {:?}",
node);
// point to what was found, if there's an
None => sess.fatal(message.as_slice())
}
}
- };
- let analysis = phase_3_run_analysis_passes(sess, &krate, ast_map);
- print_flowgraph(analysis, block, out)
+ }
}
_ => {
pprust::print_crate(sess.codemap(),
}
-fn print_flowgraph<W:io::Writer>(analysis: CrateAnalysis,
- block: ast::P<ast::Block>,
+fn print_flowgraph<W:io::Writer>(variants: Vec<borrowck_dot::Variant>,
+ analysis: CrateAnalysis,
+ code: blocks::Code,
mut out: W) -> io::IoResult<()> {
let ty_cx = &analysis.ty_cx;
- let cfg = cfg::CFG::new(ty_cx, &*block);
- let lcfg = LabelledCFG { ast_map: &ty_cx.map,
- cfg: &cfg,
- name: format!("block{}", block.id), };
+ let cfg = match code {
+ blocks::BlockCode(block) => cfg::CFG::new(ty_cx, &*block),
+ blocks::FnLikeCode(fn_like) => cfg::CFG::new(ty_cx, fn_like.body()),
+ };
debug!("cfg: {:?}", cfg);
- let r = dot::render(&lcfg, &mut out);
- return expand_err_details(r);
+
+ match code {
+ _ if variants.len() == 0 => {
+ let lcfg = LabelledCFG {
+ ast_map: &ty_cx.map,
+ cfg: &cfg,
+ name: format!("node_{}", code.id()),
+ };
+ let r = dot::render(&lcfg, &mut out);
+ return expand_err_details(r);
+ }
+ blocks::BlockCode(_) => {
+ ty_cx.sess.err("--pretty flowgraph with -Z flowgraph-print \
+ annotations requires fn-like node id.");
+ return Ok(())
+ }
+ blocks::FnLikeCode(fn_like) => {
+ let fn_parts = FnPartsWithCFG::from_fn_like(&fn_like, &cfg);
+ let (bccx, analysis_data) =
+ borrowck::build_borrowck_dataflow_data_for_fn(ty_cx, fn_parts);
+
+ let lcfg = LabelledCFG {
+ ast_map: &ty_cx.map,
+ cfg: &cfg,
+ name: format!("node_{}", code.id()),
+ };
+ let lcfg = borrowck_dot::DataflowLabeller {
+ inner: lcfg,
+ variants: variants,
+ borrowck_ctxt: &bccx,
+ analysis_data: &analysis_data,
+ };
+ let r = dot::render(&lcfg, &mut out);
+ return expand_err_details(r);
+ }
+ }
fn expand_err_details(r: io::IoResult<()>) -> io::IoResult<()> {
r.map_err(|ioerr| {
}).collect()
}
+pub fn collect_crate_metadata(session: &Session,
+ _attrs: &[ast::Attribute]) -> Vec<String> {
+ session.opts.cg.metadata.clone()
+}
+
pub struct OutputFilenames {
pub out_directory: Path,
pub out_filestem: String,
None => Path::new(".")
};
- let mut stem = input.filestem();
+ // If a crate name is present, we use it as the link name
+ let stem = sess.opts.crate_name.clone().or_else(|| {
+ attr::find_crate_name(attrs).map(|n| n.get().to_string())
+ }).or_else(|| {
+ // NB: this clause can be removed once #[crate_id] is no longer
+ // deprecated.
+ //
+ // Also note that this will be warned about later so we don't
+ // warn about it here.
+ use syntax::crateid::CrateId;
+ attrs.iter().find(|at| at.check_name("crate_id"))
+ .and_then(|at| at.value_str())
+ .and_then(|s| from_str::<CrateId>(s.get()))
+ .map(|id| id.name)
+ }).unwrap_or(input.filestem());
- // If a crateid is present, we use it as the link name
- let crateid = attr::find_crateid(attrs);
- match crateid {
- None => {}
- Some(crateid) => stem = crateid.name.to_string(),
- }
OutputFilenames {
out_directory: dirpath,
out_filestem: stem,
use syntax::ast;
use syntax::parse;
use syntax::diagnostic::Emitter;
+use syntax::diagnostics;
use getopts;
Some(matches) => matches,
None => return
};
- let sopts = config::build_session_options(&matches);
+ let descriptions = diagnostics::registry::Registry::new(super::DIAGNOSTICS);
+ match matches.opt_str("explain") {
+ Some(ref code) => {
+ match descriptions.find_description(code.as_slice()) {
+ Some(ref description) => {
+ println!("{}", description);
+ }
+ None => {
+ early_error(format!("no extended information for {}", code).as_slice());
+ }
+ }
+ return;
+ },
+ None => ()
+ }
+
+ let sopts = config::build_session_options(&matches);
let (input, input_file_path) = match matches.free.len() {
0u => {
if sopts.describe_lints {
_ => early_error("multiple input filenames provided")
};
- let sess = build_session(sopts, input_file_path);
+ let sess = build_session(sopts, input_file_path, descriptions);
let cfg = config::build_configuration(&sess);
let odir = matches.opt_str("out-dir").map(|o| Path::new(o));
let ofile = matches.opt_str("o").map(|o| Path::new(o));
match getopts::getopts(args.as_slice(), config::optgroups().as_slice()) {
Ok(m) => m,
Err(f) => {
- early_error(f.to_str().as_slice());
+ early_error(f.to_string().as_slice());
}
};
}
if cg_flags.contains(&"passes=list".to_string()) {
- unsafe { ::lib::llvm::llvm::LLVMRustPrintPasses(); }
+ unsafe { ::llvm::LLVMRustPrintPasses(); }
return None;
}
odir: &Option<Path>,
ofile: &Option<Path>)
-> bool {
- let (crate_id, crate_name, crate_file_name) = sess.opts.print_metas;
+ let (crate_name, crate_file_name) = sess.opts.print_metas;
// these nasty nested conditions are to avoid doing extra work
- if crate_id || crate_name || crate_file_name {
+ if crate_name || crate_file_name {
let attrs = parse_crate_attrs(sess, input);
let t_outputs = driver::build_output_filenames(input,
odir,
ofile,
attrs.as_slice(),
sess);
- let id = link::find_crate_id(attrs.as_slice(),
- t_outputs.out_filestem.as_slice());
+ let id = link::find_crate_name(Some(sess), attrs.as_slice(), input);
- if crate_id {
- println!("{}", id.to_str());
- }
if crate_name {
- println!("{}", id.name);
+ println!("{}", id);
}
if crate_file_name {
let crate_types = driver::collect_crate_types(sess, attrs.as_slice());
+ let metadata = driver::collect_crate_metadata(sess, attrs.as_slice());
+ *sess.crate_metadata.borrow_mut() = metadata;
for &style in crate_types.iter() {
- let fname = link::filename_for_input(sess, style, &id,
+ let fname = link::filename_for_input(sess, style, id.as_slice(),
&t_outputs.with_extension(""));
println!("{}", fname.filename_display());
}
}
pub fn early_error(msg: &str) -> ! {
- let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto);
- emitter.emit(None, msg, diagnostic::Fatal);
+ let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
+ emitter.emit(None, msg, None, diagnostic::Fatal);
fail!(diagnostic::FatalError);
}
+pub fn early_warn(msg: &str) {
+ let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
+ emitter.emit(None, msg, None, diagnostic::Warning);
+}
+
pub fn list_metadata(sess: &Session, path: &Path,
out: &mut io::Writer) -> io::IoResult<()> {
metadata::loader::list_file_metadata(sess.targ_cfg.os, path, out)
Err(value) => {
// Task failed without emitting a fatal diagnostic
if !value.is::<diagnostic::FatalError>() {
- let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto);
+ let mut emitter = diagnostic::EmitterWriter::stderr(diagnostic::Auto, None);
// a .span_bug or .bug call has already printed what
// it wants to print.
emitter.emit(
None,
"unexpected failure",
+ None,
diagnostic::Bug);
}
"run with `RUST_BACKTRACE=1` for a backtrace".to_string(),
];
for note in xs.iter() {
- emitter.emit(None, note.as_slice(), diagnostic::Note)
+ emitter.emit(None, note.as_slice(), None, diagnostic::Note)
}
- match r.read_to_str() {
+ match r.read_to_string() {
Ok(s) => println!("{}", s),
Err(e) => {
emitter.emit(None,
format!("failed to read internal \
stderr: {}",
e).as_slice(),
+ None,
diagnostic::Error)
}
}
use syntax::ast::NodeId;
use syntax::codemap::Span;
use syntax::diagnostic;
+use syntax::diagnostics;
use syntax::parse;
use syntax::parse::token;
use syntax::parse::ParseSess;
use std::os;
use std::cell::{Cell, RefCell};
-
+// Represents the data associated with a compilation
+// session for a single crate.
pub struct Session {
pub targ_cfg: config::Config,
pub opts: config::Options,
pub lints: RefCell<NodeMap<Vec<(lint::LintId, codemap::Span, String)>>>,
pub node_id: Cell<ast::NodeId>,
pub crate_types: RefCell<Vec<config::CrateType>>,
+ pub crate_metadata: RefCell<Vec<String>>,
pub features: front::feature_gate::Features,
/// The maximum recursion limit for potentially infinitely recursive
pub fn span_err(&self, sp: Span, msg: &str) {
self.diagnostic().span_err(sp, msg)
}
+ pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
+ self.diagnostic().span_err_with_code(sp, msg, code)
+ }
pub fn err(&self, msg: &str) {
self.diagnostic().handler().err(msg)
}
}
pub fn build_session(sopts: config::Options,
- local_crate_source_file: Option<Path>)
+ local_crate_source_file: Option<Path>,
+ registry: diagnostics::registry::Registry)
-> Session {
let codemap = codemap::CodeMap::new();
let diagnostic_handler =
- diagnostic::default_handler(sopts.color);
+ diagnostic::default_handler(sopts.color, Some(registry));
let span_diagnostic_handler =
diagnostic::mk_span_handler(diagnostic_handler, codemap);
lints: RefCell::new(NodeMap::new()),
node_id: Cell::new(1),
crate_types: RefCell::new(Vec::new()),
+ crate_metadata: RefCell::new(Vec::new()),
features: front::feature_gate::Features::new(),
recursion_limit: Cell::new(64),
};
use std::gc::{Gc, GC};
+/// A folder that strips out items that do not belong in the current
+/// configuration.
struct Context<'a> {
in_cfg: |attrs: &[ast::Attribute]|: 'a -> bool,
}
fn fold_expr(&mut self, expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
fold_expr(self, expr)
}
+ fn fold_mac(&mut self, mac: &ast::Mac) -> ast::Mac {
+ fold::fold_mac(mac, self)
+ }
}
pub fn strip_items(krate: ast::Crate,
.map(|x| *x).collect();
ast::ItemImpl((*a).clone(), (*b).clone(), c, methods)
}
- ast::ItemTrait(ref a, b, ref c, ref methods) => {
+ ast::ItemTrait(ref a, ref b, ref c, ref methods) => {
let methods = methods.iter()
.filter(|m| trait_method_in_cfg(cx, *m) )
.map(|x| (*x).clone())
.collect();
- ast::ItemTrait((*a).clone(), b, (*c).clone(), methods)
+ ast::ItemTrait((*a).clone(), (*b).clone(), (*c).clone(), methods)
}
ast::ItemStruct(ref def, ref generics) => {
ast::ItemStruct(fold_struct(cx, &**def), generics.clone())
("quad_precision_float", Removed),
+ ("rustc_diagnostic_macros", Active),
+
// A temporary feature gate used to enable parser extensions needed
// to bootstrap fix for #5723.
("issue_5723_bootstrap", Active),
pub default_type_params: Cell<bool>,
pub issue_5723_bootstrap: Cell<bool>,
pub overloaded_calls: Cell<bool>,
+ pub rustc_diagnostic_macros: Cell<bool>
}
impl Features {
default_type_params: Cell::new(false),
issue_5723_bootstrap: Cell::new(false),
overloaded_calls: Cell::new(false),
+ rustc_diagnostic_macros: Cell::new(false)
}
}
}
sess.features.default_type_params.set(cx.has_feature("default_type_params"));
sess.features.issue_5723_bootstrap.set(cx.has_feature("issue_5723_bootstrap"));
sess.features.overloaded_calls.set(cx.has_feature("overloaded_calls"));
+ sess.features.rustc_diagnostic_macros.set(cx.has_feature("rustc_diagnostic_macros"));
}
use std::mem;
use std::gc::{Gc, GC};
-pub static VERSION: &'static str = "0.11.0";
-
pub fn maybe_inject_crates_ref(sess: &Session, krate: ast::Crate)
-> ast::Crate {
if use_std(&krate) {
sess: &'a Session,
}
-pub fn with_version(krate: &str) -> Option<(InternedString, ast::StrStyle)> {
- match option_env!("CFG_DISABLE_INJECT_STD_VERSION") {
- Some("1") => None,
- _ => {
- Some((token::intern_and_get_ident(format!("{}#{}",
- krate,
- VERSION).as_slice()),
- ast::CookedStr))
- }
- }
-}
-
impl<'a> fold::Folder for StandardLibraryInjector<'a> {
fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
let mut vis = vec!(ast::ViewItem {
node: ast::ViewItemExternCrate(token::str_to_ident("std"),
- with_version("std"),
- ast::DUMMY_NODE_ID),
+ None,
+ ast::DUMMY_NODE_ID),
attrs: vec!(
attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
InternedString::new("phase"),
if use_start(&krate) && any_exe {
vis.push(ast::ViewItem {
node: ast::ViewItemExternCrate(token::str_to_ident("native"),
- with_version("native"),
- ast::DUMMY_NODE_ID),
+ None,
+ ast::DUMMY_NODE_ID),
attrs: Vec::new(),
vis: ast::Inherited,
span: DUMMY_SP
use driver::session::Session;
use front::config;
-use front::std_inject::with_version;
use std::cell::RefCell;
use std::gc::{Gc, GC};
ext_cx: ExtCtxt::new(&sess.parse_sess, sess.opts.cfg.clone(),
ExpansionConfig {
deriving_hash_type_parameter: false,
- crate_id: from_str("test").unwrap(),
+ crate_name: "test".to_string(),
}),
path: RefCell::new(Vec::new()),
testfns: RefCell::new(Vec::new()),
ast::DUMMY_NODE_ID))),
ast::Public)
} else {
- (ast::ViewItemExternCrate(id_test,
- with_version("test"),
- ast::DUMMY_NODE_ID),
+ (ast::ViewItemExternCrate(id_test, None, ast::DUMMY_NODE_ID),
ast::Inherited)
};
ast::ViewItem {
span: DUMMY_SP,
};
- debug!("Synthetic test module:\n{}\n", pprust::item_to_str(&item));
+ debug!("Synthetic test module:\n{}\n", pprust::item_to_string(&item));
box(GC) item
}
}
fn is_test_crate(krate: &ast::Crate) -> bool {
- match attr::find_crateid(krate.attrs.as_slice()) {
- Some(ref s) if "test" == s.name.as_slice() => true,
+ match attr::find_crate_name(krate.attrs.as_slice()) {
+ Some(ref s) if "test" == s.get().as_slice() => true,
_ => false
}
}
*/
-#![crate_id = "rustc#0.11.0"]
+#![crate_name = "rustc"]
#![experimental]
#![comment = "The Rust compiler"]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+ html_root_url = "http://doc.rust-lang.org/master/")]
#![allow(deprecated)]
#![feature(macro_rules, globs, struct_variant, managed_boxes, quote)]
#![feature(default_type_params, phase, unsafe_destructor)]
+#![allow(unknown_features)] // NOTE: Remove after next snapshot
+#![feature(rustc_diagnostic_macros)]
+
extern crate arena;
extern crate debug;
extern crate flate;
extern crate getopts;
extern crate graphviz;
extern crate libc;
+extern crate llvm = "rustc_llvm";
+extern crate rustc_back = "rustc_back";
extern crate serialize;
-extern crate syntax;
extern crate time;
#[phase(plugin, link)] extern crate log;
+#[phase(plugin, link)] extern crate syntax;
+
+mod diagnostics;
+
+pub mod back {
+ pub use rustc_back::abi;
+ pub use rustc_back::archive;
+ pub use rustc_back::arm;
+ pub use rustc_back::mips;
+ pub use rustc_back::mipsel;
+ pub use rustc_back::rpath;
+ pub use rustc_back::svh;
+ pub use rustc_back::target_strs;
+ pub use rustc_back::x86;
+ pub use rustc_back::x86_64;
+
+ pub mod link;
+ pub mod lto;
+
+}
pub mod middle {
pub mod def;
pub mod show_span;
}
-pub mod back {
- pub mod abi;
- pub mod archive;
- pub mod arm;
- pub mod link;
- pub mod lto;
- pub mod mips;
- pub mod mipsel;
- pub mod rpath;
- pub mod svh;
- pub mod target_strs;
- pub mod x86;
- pub mod x86_64;
-}
-
pub mod metadata;
pub mod driver;
pub mod lint;
pub mod util {
+ pub use rustc_back::fs;
+ pub use rustc_back::sha2;
+
pub mod common;
pub mod ppaux;
- pub mod sha2;
pub mod nodemap;
- pub mod fs;
}
pub mod lib {
- pub mod llvm;
- pub mod llvmdeps;
+ pub use llvm;
}
+__build_diagnostic_array!(DIAGNOSTICS)
+
// A private module so that macro-expanded idents like
// `::rustc::lint::Lint` will also work in `rustc` itself.
//
+++ /dev/null
-// Copyright 2012-2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(non_uppercase_pattern_statics)]
-#![allow(non_camel_case_types)]
-#![allow(non_snake_case_functions)]
-#![allow(dead_code)]
-
-use std::c_str::ToCStr;
-use std::cell::RefCell;
-use std::collections::HashMap;
-use libc::{c_uint, c_ushort, c_void, free, uint64_t};
-use std::str::raw::from_c_str;
-
-use middle::trans::type_::Type;
-
-pub type Opcode = u32;
-pub type Bool = c_uint;
-
-pub static True: Bool = 1 as Bool;
-pub static False: Bool = 0 as Bool;
-
-// Consts for the LLVM CallConv type, pre-cast to uint.
-
-#[deriving(PartialEq)]
-pub enum CallConv {
- CCallConv = 0,
- FastCallConv = 8,
- ColdCallConv = 9,
- X86StdcallCallConv = 64,
- X86FastcallCallConv = 65,
- X86_64_Win64 = 79,
-}
-
-pub enum Visibility {
- LLVMDefaultVisibility = 0,
- HiddenVisibility = 1,
- ProtectedVisibility = 2,
-}
-
-// This enum omits the obsolete (and no-op) linkage types DLLImportLinkage,
-// DLLExportLinkage, GhostLinkage and LinkOnceODRAutoHideLinkage.
-// LinkerPrivateLinkage and LinkerPrivateWeakLinkage are not included either;
-// they've been removed in upstream LLVM commit r203866.
-pub enum Linkage {
- ExternalLinkage = 0,
- AvailableExternallyLinkage = 1,
- LinkOnceAnyLinkage = 2,
- LinkOnceODRLinkage = 3,
- WeakAnyLinkage = 5,
- WeakODRLinkage = 6,
- AppendingLinkage = 7,
- InternalLinkage = 8,
- PrivateLinkage = 9,
- ExternalWeakLinkage = 12,
- CommonLinkage = 14,
-}
-
-#[deriving(Clone)]
-pub enum Attribute {
- ZExtAttribute = 1 << 0,
- SExtAttribute = 1 << 1,
- NoReturnAttribute = 1 << 2,
- InRegAttribute = 1 << 3,
- StructRetAttribute = 1 << 4,
- NoUnwindAttribute = 1 << 5,
- NoAliasAttribute = 1 << 6,
- ByValAttribute = 1 << 7,
- NestAttribute = 1 << 8,
- ReadNoneAttribute = 1 << 9,
- ReadOnlyAttribute = 1 << 10,
- NoInlineAttribute = 1 << 11,
- AlwaysInlineAttribute = 1 << 12,
- OptimizeForSizeAttribute = 1 << 13,
- StackProtectAttribute = 1 << 14,
- StackProtectReqAttribute = 1 << 15,
- AlignmentAttribute = 31 << 16,
- NoCaptureAttribute = 1 << 21,
- NoRedZoneAttribute = 1 << 22,
- NoImplicitFloatAttribute = 1 << 23,
- NakedAttribute = 1 << 24,
- InlineHintAttribute = 1 << 25,
- StackAttribute = 7 << 26,
- ReturnsTwiceAttribute = 1 << 29,
- UWTableAttribute = 1 << 30,
- NonLazyBindAttribute = 1 << 31,
-}
-
-#[repr(u64)]
-pub enum OtherAttribute {
- // The following are not really exposed in
- // the LLVM c api so instead to add these
- // we call a wrapper function in RustWrapper
- // that uses the C++ api.
- SanitizeAddressAttribute = 1 << 32,
- MinSizeAttribute = 1 << 33,
- NoDuplicateAttribute = 1 << 34,
- StackProtectStrongAttribute = 1 << 35,
- SanitizeThreadAttribute = 1 << 36,
- SanitizeMemoryAttribute = 1 << 37,
- NoBuiltinAttribute = 1 << 38,
- ReturnedAttribute = 1 << 39,
- ColdAttribute = 1 << 40,
- BuiltinAttribute = 1 << 41,
- OptimizeNoneAttribute = 1 << 42,
- InAllocaAttribute = 1 << 43,
- NonNullAttribute = 1 << 44,
-}
-
-#[repr(C)]
-pub enum AttributeSet {
- ReturnIndex = 0,
- FunctionIndex = !0
-}
-
-// enum for the LLVM IntPredicate type
-pub enum IntPredicate {
- IntEQ = 32,
- IntNE = 33,
- IntUGT = 34,
- IntUGE = 35,
- IntULT = 36,
- IntULE = 37,
- IntSGT = 38,
- IntSGE = 39,
- IntSLT = 40,
- IntSLE = 41,
-}
-
-// enum for the LLVM RealPredicate type
-pub enum RealPredicate {
- RealPredicateFalse = 0,
- RealOEQ = 1,
- RealOGT = 2,
- RealOGE = 3,
- RealOLT = 4,
- RealOLE = 5,
- RealONE = 6,
- RealORD = 7,
- RealUNO = 8,
- RealUEQ = 9,
- RealUGT = 10,
- RealUGE = 11,
- RealULT = 12,
- RealULE = 13,
- RealUNE = 14,
- RealPredicateTrue = 15,
-}
-
-// The LLVM TypeKind type - must stay in sync with the def of
-// LLVMTypeKind in llvm/include/llvm-c/Core.h
-#[deriving(PartialEq)]
-#[repr(C)]
-pub enum TypeKind {
- Void = 0,
- Half = 1,
- Float = 2,
- Double = 3,
- X86_FP80 = 4,
- FP128 = 5,
- PPC_FP128 = 6,
- Label = 7,
- Integer = 8,
- Function = 9,
- Struct = 10,
- Array = 11,
- Pointer = 12,
- Vector = 13,
- Metadata = 14,
- X86_MMX = 15,
-}
-
-#[repr(C)]
-pub enum AtomicBinOp {
- Xchg = 0,
- Add = 1,
- Sub = 2,
- And = 3,
- Nand = 4,
- Or = 5,
- Xor = 6,
- Max = 7,
- Min = 8,
- UMax = 9,
- UMin = 10,
-}
-
-#[repr(C)]
-pub enum AtomicOrdering {
- NotAtomic = 0,
- Unordered = 1,
- Monotonic = 2,
- // Consume = 3, // Not specified yet.
- Acquire = 4,
- Release = 5,
- AcquireRelease = 6,
- SequentiallyConsistent = 7
-}
-
-// Consts for the LLVMCodeGenFileType type (in include/llvm/c/TargetMachine.h)
-#[repr(C)]
-pub enum FileType {
- AssemblyFile = 0,
- ObjectFile = 1
-}
-
-pub enum Metadata {
- MD_dbg = 0,
- MD_tbaa = 1,
- MD_prof = 2,
- MD_fpmath = 3,
- MD_range = 4,
- MD_tbaa_struct = 5
-}
-
-// Inline Asm Dialect
-pub enum AsmDialect {
- AD_ATT = 0,
- AD_Intel = 1
-}
-
-#[deriving(PartialEq)]
-#[repr(C)]
-pub enum CodeGenOptLevel {
- CodeGenLevelNone = 0,
- CodeGenLevelLess = 1,
- CodeGenLevelDefault = 2,
- CodeGenLevelAggressive = 3,
-}
-
-#[repr(C)]
-pub enum RelocMode {
- RelocDefault = 0,
- RelocStatic = 1,
- RelocPIC = 2,
- RelocDynamicNoPic = 3,
-}
-
-#[repr(C)]
-pub enum CodeGenModel {
- CodeModelDefault = 0,
- CodeModelJITDefault = 1,
- CodeModelSmall = 2,
- CodeModelKernel = 3,
- CodeModelMedium = 4,
- CodeModelLarge = 5,
-}
-
-// Opaque pointer types
-pub enum Module_opaque {}
-pub type ModuleRef = *mut Module_opaque;
-pub enum Context_opaque {}
-pub type ContextRef = *mut Context_opaque;
-pub enum Type_opaque {}
-pub type TypeRef = *mut Type_opaque;
-pub enum Value_opaque {}
-pub type ValueRef = *mut Value_opaque;
-pub enum BasicBlock_opaque {}
-pub type BasicBlockRef = *mut BasicBlock_opaque;
-pub enum Builder_opaque {}
-pub type BuilderRef = *mut Builder_opaque;
-pub enum ExecutionEngine_opaque {}
-pub type ExecutionEngineRef = *mut ExecutionEngine_opaque;
-pub enum MemoryBuffer_opaque {}
-pub type MemoryBufferRef = *mut MemoryBuffer_opaque;
-pub enum PassManager_opaque {}
-pub type PassManagerRef = *mut PassManager_opaque;
-pub enum PassManagerBuilder_opaque {}
-pub type PassManagerBuilderRef = *mut PassManagerBuilder_opaque;
-pub enum Use_opaque {}
-pub type UseRef = *mut Use_opaque;
-pub enum TargetData_opaque {}
-pub type TargetDataRef = *mut TargetData_opaque;
-pub enum ObjectFile_opaque {}
-pub type ObjectFileRef = *mut ObjectFile_opaque;
-pub enum SectionIterator_opaque {}
-pub type SectionIteratorRef = *mut SectionIterator_opaque;
-pub enum Pass_opaque {}
-pub type PassRef = *mut Pass_opaque;
-pub enum TargetMachine_opaque {}
-pub type TargetMachineRef = *mut TargetMachine_opaque;
-pub enum Archive_opaque {}
-pub type ArchiveRef = *mut Archive_opaque;
-
-pub mod debuginfo {
- use super::{ValueRef};
-
- pub enum DIBuilder_opaque {}
- pub type DIBuilderRef = *mut DIBuilder_opaque;
-
- pub type DIDescriptor = ValueRef;
- pub type DIScope = DIDescriptor;
- pub type DILocation = DIDescriptor;
- pub type DIFile = DIScope;
- pub type DILexicalBlock = DIScope;
- pub type DISubprogram = DIScope;
- pub type DIType = DIDescriptor;
- pub type DIBasicType = DIType;
- pub type DIDerivedType = DIType;
- pub type DICompositeType = DIDerivedType;
- pub type DIVariable = DIDescriptor;
- pub type DIGlobalVariable = DIDescriptor;
- pub type DIArray = DIDescriptor;
- pub type DISubrange = DIDescriptor;
-
- pub enum DIDescriptorFlags {
- FlagPrivate = 1 << 0,
- FlagProtected = 1 << 1,
- FlagFwdDecl = 1 << 2,
- FlagAppleBlock = 1 << 3,
- FlagBlockByrefStruct = 1 << 4,
- FlagVirtual = 1 << 5,
- FlagArtificial = 1 << 6,
- FlagExplicit = 1 << 7,
- FlagPrototyped = 1 << 8,
- FlagObjcClassComplete = 1 << 9,
- FlagObjectPointer = 1 << 10,
- FlagVector = 1 << 11,
- FlagStaticMember = 1 << 12
- }
-}
-
-pub mod llvm {
- use super::{AtomicBinOp, AtomicOrdering, BasicBlockRef, ExecutionEngineRef};
- use super::{Bool, BuilderRef, ContextRef, MemoryBufferRef, ModuleRef};
- use super::{ObjectFileRef, Opcode, PassManagerRef, PassManagerBuilderRef};
- use super::{SectionIteratorRef, TargetDataRef, TypeKind, TypeRef, UseRef};
- use super::{ValueRef, TargetMachineRef, FileType, ArchiveRef};
- use super::{CodeGenModel, RelocMode, CodeGenOptLevel};
- use super::debuginfo::*;
- use libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong,
- size_t, uint64_t};
-
- // Link to our native llvm bindings (things that we need to use the C++ api
- // for) and because llvm is written in C++ we need to link against libstdc++
- //
- // You'll probably notice that there is an omission of all LLVM libraries
- // from this location. This is because the set of LLVM libraries that we
- // link to is mostly defined by LLVM, and the `llvm-config` tool is used to
- // figure out the exact set of libraries. To do this, the build system
- // generates an llvmdeps.rs file next to this one which will be
- // automatically updated whenever LLVM is updated to include an up-to-date
- // set of the libraries we need to link to LLVM for.
- #[link(name = "rustllvm", kind = "static")]
- extern {
- /* Create and destroy contexts. */
- pub fn LLVMContextCreate() -> ContextRef;
- pub fn LLVMContextDispose(C: ContextRef);
- pub fn LLVMGetMDKindIDInContext(C: ContextRef,
- Name: *const c_char,
- SLen: c_uint)
- -> c_uint;
-
- /* Create and destroy modules. */
- pub fn LLVMModuleCreateWithNameInContext(ModuleID: *const c_char,
- C: ContextRef)
- -> ModuleRef;
- pub fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef;
- pub fn LLVMDisposeModule(M: ModuleRef);
-
- /** Data layout. See Module::getDataLayout. */
- pub fn LLVMGetDataLayout(M: ModuleRef) -> *const c_char;
- pub fn LLVMSetDataLayout(M: ModuleRef, Triple: *const c_char);
-
- /** Target triple. See Module::getTargetTriple. */
- pub fn LLVMGetTarget(M: ModuleRef) -> *const c_char;
- pub fn LLVMSetTarget(M: ModuleRef, Triple: *const c_char);
-
- /** See Module::dump. */
- pub fn LLVMDumpModule(M: ModuleRef);
-
- /** See Module::setModuleInlineAsm. */
- pub fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *const c_char);
-
- /** See llvm::LLVMTypeKind::getTypeID. */
- pub fn LLVMGetTypeKind(Ty: TypeRef) -> TypeKind;
-
- /** See llvm::LLVMType::getContext. */
- pub fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef;
-
- /* Operations on integer types */
- pub fn LLVMInt1TypeInContext(C: ContextRef) -> TypeRef;
- pub fn LLVMInt8TypeInContext(C: ContextRef) -> TypeRef;
- pub fn LLVMInt16TypeInContext(C: ContextRef) -> TypeRef;
- pub fn LLVMInt32TypeInContext(C: ContextRef) -> TypeRef;
- pub fn LLVMInt64TypeInContext(C: ContextRef) -> TypeRef;
- pub fn LLVMIntTypeInContext(C: ContextRef, NumBits: c_uint)
- -> TypeRef;
-
- pub fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint;
-
- /* Operations on real types */
- pub fn LLVMFloatTypeInContext(C: ContextRef) -> TypeRef;
- pub fn LLVMDoubleTypeInContext(C: ContextRef) -> TypeRef;
- pub fn LLVMX86FP80TypeInContext(C: ContextRef) -> TypeRef;
- pub fn LLVMFP128TypeInContext(C: ContextRef) -> TypeRef;
- pub fn LLVMPPCFP128TypeInContext(C: ContextRef) -> TypeRef;
-
- /* Operations on function types */
- pub fn LLVMFunctionType(ReturnType: TypeRef,
- ParamTypes: *const TypeRef,
- ParamCount: c_uint,
- IsVarArg: Bool)
- -> TypeRef;
- pub fn LLVMIsFunctionVarArg(FunctionTy: TypeRef) -> Bool;
- pub fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef;
- pub fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint;
- pub fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *const TypeRef);
-
- /* Operations on struct types */
- pub fn LLVMStructTypeInContext(C: ContextRef,
- ElementTypes: *const TypeRef,
- ElementCount: c_uint,
- Packed: Bool)
- -> TypeRef;
- pub fn LLVMCountStructElementTypes(StructTy: TypeRef) -> c_uint;
- pub fn LLVMGetStructElementTypes(StructTy: TypeRef,
- Dest: *mut TypeRef);
- pub fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool;
-
- /* Operations on array, pointer, and vector types (sequence types) */
- pub fn LLVMRustArrayType(ElementType: TypeRef, ElementCount: u64) -> TypeRef;
- pub fn LLVMPointerType(ElementType: TypeRef, AddressSpace: c_uint)
- -> TypeRef;
- pub fn LLVMVectorType(ElementType: TypeRef, ElementCount: c_uint)
- -> TypeRef;
-
- pub fn LLVMGetElementType(Ty: TypeRef) -> TypeRef;
- pub fn LLVMGetArrayLength(ArrayTy: TypeRef) -> c_uint;
- pub fn LLVMGetPointerAddressSpace(PointerTy: TypeRef) -> c_uint;
- pub fn LLVMGetPointerToGlobal(EE: ExecutionEngineRef, V: ValueRef)
- -> *const ();
- pub fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint;
-
- /* Operations on other types */
- pub fn LLVMVoidTypeInContext(C: ContextRef) -> TypeRef;
- pub fn LLVMLabelTypeInContext(C: ContextRef) -> TypeRef;
- pub fn LLVMMetadataTypeInContext(C: ContextRef) -> TypeRef;
-
- /* Operations on all values */
- pub fn LLVMTypeOf(Val: ValueRef) -> TypeRef;
- pub fn LLVMGetValueName(Val: ValueRef) -> *const c_char;
- pub fn LLVMSetValueName(Val: ValueRef, Name: *const c_char);
- pub fn LLVMDumpValue(Val: ValueRef);
- pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
- pub fn LLVMHasMetadata(Val: ValueRef) -> c_int;
- pub fn LLVMGetMetadata(Val: ValueRef, KindID: c_uint) -> ValueRef;
- pub fn LLVMSetMetadata(Val: ValueRef, KindID: c_uint, Node: ValueRef);
-
- /* Operations on Uses */
- pub fn LLVMGetFirstUse(Val: ValueRef) -> UseRef;
- pub fn LLVMGetNextUse(U: UseRef) -> UseRef;
- pub fn LLVMGetUser(U: UseRef) -> ValueRef;
- pub fn LLVMGetUsedValue(U: UseRef) -> ValueRef;
-
- /* Operations on Users */
- pub fn LLVMGetNumOperands(Val: ValueRef) -> c_int;
- pub fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
- pub fn LLVMSetOperand(Val: ValueRef, Index: c_uint, Op: ValueRef);
-
- /* Operations on constants of any type */
- pub fn LLVMConstNull(Ty: TypeRef) -> ValueRef;
- /* all zeroes */
- pub fn LLVMConstAllOnes(Ty: TypeRef) -> ValueRef;
- pub fn LLVMConstICmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef)
- -> ValueRef;
- pub fn LLVMConstFCmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef)
- -> ValueRef;
- /* only for int/vector */
- pub fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
- pub fn LLVMIsConstant(Val: ValueRef) -> Bool;
- pub fn LLVMIsNull(Val: ValueRef) -> Bool;
- pub fn LLVMIsUndef(Val: ValueRef) -> Bool;
- pub fn LLVMConstPointerNull(Ty: TypeRef) -> ValueRef;
-
- /* Operations on metadata */
- pub fn LLVMMDStringInContext(C: ContextRef,
- Str: *const c_char,
- SLen: c_uint)
- -> ValueRef;
- pub fn LLVMMDNodeInContext(C: ContextRef,
- Vals: *const ValueRef,
- Count: c_uint)
- -> ValueRef;
- pub fn LLVMAddNamedMetadataOperand(M: ModuleRef,
- Str: *const c_char,
- Val: ValueRef);
-
- /* Operations on scalar constants */
- pub fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool)
- -> ValueRef;
- pub fn LLVMConstIntOfString(IntTy: TypeRef, Text: *const c_char, Radix: u8)
- -> ValueRef;
- pub fn LLVMConstIntOfStringAndSize(IntTy: TypeRef,
- Text: *const c_char,
- SLen: c_uint,
- Radix: u8)
- -> ValueRef;
- pub fn LLVMConstReal(RealTy: TypeRef, N: f64) -> ValueRef;
- pub fn LLVMConstRealOfString(RealTy: TypeRef, Text: *const c_char)
- -> ValueRef;
- pub fn LLVMConstRealOfStringAndSize(RealTy: TypeRef,
- Text: *const c_char,
- SLen: c_uint)
- -> ValueRef;
- pub fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
- pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
-
-
- /* Operations on composite constants */
- pub fn LLVMConstStringInContext(C: ContextRef,
- Str: *const c_char,
- Length: c_uint,
- DontNullTerminate: Bool)
- -> ValueRef;
- pub fn LLVMConstStructInContext(C: ContextRef,
- ConstantVals: *const ValueRef,
- Count: c_uint,
- Packed: Bool)
- -> ValueRef;
-
- pub fn LLVMConstArray(ElementTy: TypeRef,
- ConstantVals: *const ValueRef,
- Length: c_uint)
- -> ValueRef;
- pub fn LLVMConstVector(ScalarConstantVals: *const ValueRef, Size: c_uint)
- -> ValueRef;
-
- /* Constant expressions */
- pub fn LLVMAlignOf(Ty: TypeRef) -> ValueRef;
- pub fn LLVMSizeOf(Ty: TypeRef) -> ValueRef;
- pub fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef;
- pub fn LLVMConstNSWNeg(ConstantVal: ValueRef) -> ValueRef;
- pub fn LLVMConstNUWNeg(ConstantVal: ValueRef) -> ValueRef;
- pub fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef;
- pub fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef;
- pub fn LLVMConstAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstNSWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstNUWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstFAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstNSWSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstNUWSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstFSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstNSWMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstNUWMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstFMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstUDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstSDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstExactSDiv(LHSConstant: ValueRef,
- RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstFDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstURem(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstSRem(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstFRem(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstAnd(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstOr(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstXor(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstShl(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstLShr(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstAShr(LHSConstant: ValueRef, RHSConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstGEP(ConstantVal: ValueRef,
- ConstantIndices: *const ValueRef,
- NumIndices: c_uint)
- -> ValueRef;
- pub fn LLVMConstInBoundsGEP(ConstantVal: ValueRef,
- ConstantIndices: *const ValueRef,
- NumIndices: c_uint)
- -> ValueRef;
- pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstSExt(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstFPTrunc(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstFPExt(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstZExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstSExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstTruncOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstIntCast(ConstantVal: ValueRef,
- ToType: TypeRef,
- isSigned: Bool)
- -> ValueRef;
- pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: TypeRef)
- -> ValueRef;
- pub fn LLVMConstSelect(ConstantCondition: ValueRef,
- ConstantIfTrue: ValueRef,
- ConstantIfFalse: ValueRef)
- -> ValueRef;
- pub fn LLVMConstExtractElement(VectorConstant: ValueRef,
- IndexConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstInsertElement(VectorConstant: ValueRef,
- ElementValueConstant: ValueRef,
- IndexConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstShuffleVector(VectorAConstant: ValueRef,
- VectorBConstant: ValueRef,
- MaskConstant: ValueRef)
- -> ValueRef;
- pub fn LLVMConstExtractValue(AggConstant: ValueRef,
- IdxList: *const c_uint,
- NumIdx: c_uint)
- -> ValueRef;
- pub fn LLVMConstInsertValue(AggConstant: ValueRef,
- ElementValueConstant: ValueRef,
- IdxList: *const c_uint,
- NumIdx: c_uint)
- -> ValueRef;
- pub fn LLVMConstInlineAsm(Ty: TypeRef,
- AsmString: *const c_char,
- Constraints: *const c_char,
- HasSideEffects: Bool,
- IsAlignStack: Bool)
- -> ValueRef;
- pub fn LLVMBlockAddress(F: ValueRef, BB: BasicBlockRef) -> ValueRef;
-
-
-
- /* Operations on global variables, functions, and aliases (globals) */
- pub fn LLVMGetGlobalParent(Global: ValueRef) -> ModuleRef;
- pub fn LLVMIsDeclaration(Global: ValueRef) -> Bool;
- pub fn LLVMGetLinkage(Global: ValueRef) -> c_uint;
- pub fn LLVMSetLinkage(Global: ValueRef, Link: c_uint);
- pub fn LLVMGetSection(Global: ValueRef) -> *const c_char;
- pub fn LLVMSetSection(Global: ValueRef, Section: *const c_char);
- pub fn LLVMGetVisibility(Global: ValueRef) -> c_uint;
- pub fn LLVMSetVisibility(Global: ValueRef, Viz: c_uint);
- pub fn LLVMGetAlignment(Global: ValueRef) -> c_uint;
- pub fn LLVMSetAlignment(Global: ValueRef, Bytes: c_uint);
-
-
- /* Operations on global variables */
- pub fn LLVMAddGlobal(M: ModuleRef, Ty: TypeRef, Name: *const c_char)
- -> ValueRef;
- pub fn LLVMAddGlobalInAddressSpace(M: ModuleRef,
- Ty: TypeRef,
- Name: *const c_char,
- AddressSpace: c_uint)
- -> ValueRef;
- pub fn LLVMGetNamedGlobal(M: ModuleRef, Name: *const c_char) -> ValueRef;
- pub fn LLVMGetFirstGlobal(M: ModuleRef) -> ValueRef;
- pub fn LLVMGetLastGlobal(M: ModuleRef) -> ValueRef;
- pub fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef;
- pub fn LLVMGetPreviousGlobal(GlobalVar: ValueRef) -> ValueRef;
- pub fn LLVMDeleteGlobal(GlobalVar: ValueRef);
- pub fn LLVMGetInitializer(GlobalVar: ValueRef) -> ValueRef;
- pub fn LLVMSetInitializer(GlobalVar: ValueRef,
- ConstantVal: ValueRef);
- pub fn LLVMIsThreadLocal(GlobalVar: ValueRef) -> Bool;
- pub fn LLVMSetThreadLocal(GlobalVar: ValueRef, IsThreadLocal: Bool);
- pub fn LLVMIsGlobalConstant(GlobalVar: ValueRef) -> Bool;
- pub fn LLVMSetGlobalConstant(GlobalVar: ValueRef, IsConstant: Bool);
-
- /* Operations on aliases */
- pub fn LLVMAddAlias(M: ModuleRef,
- Ty: TypeRef,
- Aliasee: ValueRef,
- Name: *const c_char)
- -> ValueRef;
-
- /* Operations on functions */
- pub fn LLVMAddFunction(M: ModuleRef,
- Name: *const c_char,
- FunctionTy: TypeRef)
- -> ValueRef;
- pub fn LLVMGetNamedFunction(M: ModuleRef, Name: *const c_char) -> ValueRef;
- pub fn LLVMGetFirstFunction(M: ModuleRef) -> ValueRef;
- pub fn LLVMGetLastFunction(M: ModuleRef) -> ValueRef;
- pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
- pub fn LLVMGetPreviousFunction(Fn: ValueRef) -> ValueRef;
- pub fn LLVMDeleteFunction(Fn: ValueRef);
- pub fn LLVMGetOrInsertFunction(M: ModuleRef,
- Name: *const c_char,
- FunctionTy: TypeRef)
- -> ValueRef;
- pub fn LLVMGetIntrinsicID(Fn: ValueRef) -> c_uint;
- pub fn LLVMGetFunctionCallConv(Fn: ValueRef) -> c_uint;
- pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
- pub fn LLVMGetGC(Fn: ValueRef) -> *const c_char;
- pub fn LLVMSetGC(Fn: ValueRef, Name: *const c_char);
- pub fn LLVMAddFunctionAttribute(Fn: ValueRef, index: c_uint, PA: uint64_t);
- pub fn LLVMAddFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
- pub fn LLVMRemoveFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
- pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong;
-
- /* Operations on parameters */
- pub fn LLVMCountParams(Fn: ValueRef) -> c_uint;
- pub fn LLVMGetParams(Fn: ValueRef, Params: *const ValueRef);
- pub fn LLVMGetParam(Fn: ValueRef, Index: c_uint) -> ValueRef;
- pub fn LLVMGetParamParent(Inst: ValueRef) -> ValueRef;
- pub fn LLVMGetFirstParam(Fn: ValueRef) -> ValueRef;
- pub fn LLVMGetLastParam(Fn: ValueRef) -> ValueRef;
- pub fn LLVMGetNextParam(Arg: ValueRef) -> ValueRef;
- pub fn LLVMGetPreviousParam(Arg: ValueRef) -> ValueRef;
- pub fn LLVMAddAttribute(Arg: ValueRef, PA: c_uint);
- pub fn LLVMRemoveAttribute(Arg: ValueRef, PA: c_uint);
- pub fn LLVMGetAttribute(Arg: ValueRef) -> c_uint;
- pub fn LLVMSetParamAlignment(Arg: ValueRef, align: c_uint);
-
- /* Operations on basic blocks */
- pub fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> ValueRef;
- pub fn LLVMValueIsBasicBlock(Val: ValueRef) -> Bool;
- pub fn LLVMValueAsBasicBlock(Val: ValueRef) -> BasicBlockRef;
- pub fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> ValueRef;
- pub fn LLVMCountBasicBlocks(Fn: ValueRef) -> c_uint;
- pub fn LLVMGetBasicBlocks(Fn: ValueRef, BasicBlocks: *const ValueRef);
- pub fn LLVMGetFirstBasicBlock(Fn: ValueRef) -> BasicBlockRef;
- pub fn LLVMGetLastBasicBlock(Fn: ValueRef) -> BasicBlockRef;
- pub fn LLVMGetNextBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
- pub fn LLVMGetPreviousBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
- pub fn LLVMGetEntryBasicBlock(Fn: ValueRef) -> BasicBlockRef;
-
- pub fn LLVMAppendBasicBlockInContext(C: ContextRef,
- Fn: ValueRef,
- Name: *const c_char)
- -> BasicBlockRef;
- pub fn LLVMInsertBasicBlockInContext(C: ContextRef,
- BB: BasicBlockRef,
- Name: *const c_char)
- -> BasicBlockRef;
- pub fn LLVMDeleteBasicBlock(BB: BasicBlockRef);
-
- pub fn LLVMMoveBasicBlockAfter(BB: BasicBlockRef,
- MoveAfter: BasicBlockRef);
-
- pub fn LLVMMoveBasicBlockBefore(BB: BasicBlockRef,
- MoveBefore: BasicBlockRef);
-
- /* Operations on instructions */
- pub fn LLVMGetInstructionParent(Inst: ValueRef) -> BasicBlockRef;
- pub fn LLVMGetFirstInstruction(BB: BasicBlockRef) -> ValueRef;
- pub fn LLVMGetLastInstruction(BB: BasicBlockRef) -> ValueRef;
- pub fn LLVMGetNextInstruction(Inst: ValueRef) -> ValueRef;
- pub fn LLVMGetPreviousInstruction(Inst: ValueRef) -> ValueRef;
- pub fn LLVMInstructionEraseFromParent(Inst: ValueRef);
-
- /* Operations on call sites */
- pub fn LLVMSetInstructionCallConv(Instr: ValueRef, CC: c_uint);
- pub fn LLVMGetInstructionCallConv(Instr: ValueRef) -> c_uint;
- pub fn LLVMAddInstrAttribute(Instr: ValueRef,
- index: c_uint,
- IA: c_uint);
- pub fn LLVMRemoveInstrAttribute(Instr: ValueRef,
- index: c_uint,
- IA: c_uint);
- pub fn LLVMSetInstrParamAlignment(Instr: ValueRef,
- index: c_uint,
- align: c_uint);
- pub fn LLVMAddCallSiteAttribute(Instr: ValueRef,
- index: c_uint,
- Val: uint64_t);
-
- /* Operations on call instructions (only) */
- pub fn LLVMIsTailCall(CallInst: ValueRef) -> Bool;
- pub fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool);
-
- /* Operations on load/store instructions (only) */
- pub fn LLVMGetVolatile(MemoryAccessInst: ValueRef) -> Bool;
- pub fn LLVMSetVolatile(MemoryAccessInst: ValueRef, volatile: Bool);
-
- /* Operations on phi nodes */
- pub fn LLVMAddIncoming(PhiNode: ValueRef,
- IncomingValues: *const ValueRef,
- IncomingBlocks: *const BasicBlockRef,
- Count: c_uint);
- pub fn LLVMCountIncoming(PhiNode: ValueRef) -> c_uint;
- pub fn LLVMGetIncomingValue(PhiNode: ValueRef, Index: c_uint)
- -> ValueRef;
- pub fn LLVMGetIncomingBlock(PhiNode: ValueRef, Index: c_uint)
- -> BasicBlockRef;
-
- /* Instruction builders */
- pub fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef;
- pub fn LLVMPositionBuilder(Builder: BuilderRef,
- Block: BasicBlockRef,
- Instr: ValueRef);
- pub fn LLVMPositionBuilderBefore(Builder: BuilderRef,
- Instr: ValueRef);
- pub fn LLVMPositionBuilderAtEnd(Builder: BuilderRef,
- Block: BasicBlockRef);
- pub fn LLVMGetInsertBlock(Builder: BuilderRef) -> BasicBlockRef;
- pub fn LLVMClearInsertionPosition(Builder: BuilderRef);
- pub fn LLVMInsertIntoBuilder(Builder: BuilderRef, Instr: ValueRef);
- pub fn LLVMInsertIntoBuilderWithName(Builder: BuilderRef,
- Instr: ValueRef,
- Name: *const c_char);
- pub fn LLVMDisposeBuilder(Builder: BuilderRef);
- pub fn LLVMDisposeExecutionEngine(EE: ExecutionEngineRef);
-
- /* Metadata */
- pub fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: ValueRef);
- pub fn LLVMGetCurrentDebugLocation(Builder: BuilderRef) -> ValueRef;
- pub fn LLVMSetInstDebugLocation(Builder: BuilderRef, Inst: ValueRef);
-
- /* Terminators */
- pub fn LLVMBuildRetVoid(B: BuilderRef) -> ValueRef;
- pub fn LLVMBuildRet(B: BuilderRef, V: ValueRef) -> ValueRef;
- pub fn LLVMBuildAggregateRet(B: BuilderRef,
- RetVals: *const ValueRef,
- N: c_uint)
- -> ValueRef;
- pub fn LLVMBuildBr(B: BuilderRef, Dest: BasicBlockRef) -> ValueRef;
- pub fn LLVMBuildCondBr(B: BuilderRef,
- If: ValueRef,
- Then: BasicBlockRef,
- Else: BasicBlockRef)
- -> ValueRef;
- pub fn LLVMBuildSwitch(B: BuilderRef,
- V: ValueRef,
- Else: BasicBlockRef,
- NumCases: c_uint)
- -> ValueRef;
- pub fn LLVMBuildIndirectBr(B: BuilderRef,
- Addr: ValueRef,
- NumDests: c_uint)
- -> ValueRef;
- pub fn LLVMBuildInvoke(B: BuilderRef,
- Fn: ValueRef,
- Args: *const ValueRef,
- NumArgs: c_uint,
- Then: BasicBlockRef,
- Catch: BasicBlockRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildLandingPad(B: BuilderRef,
- Ty: TypeRef,
- PersFn: ValueRef,
- NumClauses: c_uint,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildResume(B: BuilderRef, Exn: ValueRef) -> ValueRef;
- pub fn LLVMBuildUnreachable(B: BuilderRef) -> ValueRef;
-
- /* Add a case to the switch instruction */
- pub fn LLVMAddCase(Switch: ValueRef,
- OnVal: ValueRef,
- Dest: BasicBlockRef);
-
- /* Add a destination to the indirectbr instruction */
- pub fn LLVMAddDestination(IndirectBr: ValueRef, Dest: BasicBlockRef);
-
- /* Add a clause to the landing pad instruction */
- pub fn LLVMAddClause(LandingPad: ValueRef, ClauseVal: ValueRef);
-
- /* Set the cleanup on a landing pad instruction */
- pub fn LLVMSetCleanup(LandingPad: ValueRef, Val: Bool);
-
- /* Arithmetic */
- pub fn LLVMBuildAdd(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildNSWAdd(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildNUWAdd(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildFAdd(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildSub(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildNSWSub(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildNUWSub(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildFSub(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildMul(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildNSWMul(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildNUWMul(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildFMul(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildUDiv(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildSDiv(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildExactSDiv(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildFDiv(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildURem(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildSRem(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildFRem(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildShl(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildLShr(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildAShr(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildAnd(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildOr(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildXor(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildBinOp(B: BuilderRef,
- Op: Opcode,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildNSWNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildNUWNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildFNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildNot(B: BuilderRef, V: ValueRef, Name: *const c_char)
- -> ValueRef;
-
- /* Memory */
- pub fn LLVMBuildMalloc(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildArrayMalloc(B: BuilderRef,
- Ty: TypeRef,
- Val: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildAlloca(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildArrayAlloca(B: BuilderRef,
- Ty: TypeRef,
- Val: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildFree(B: BuilderRef, PointerVal: ValueRef) -> ValueRef;
- pub fn LLVMBuildLoad(B: BuilderRef,
- PointerVal: ValueRef,
- Name: *const c_char)
- -> ValueRef;
-
- pub fn LLVMBuildStore(B: BuilderRef, Val: ValueRef, Ptr: ValueRef)
- -> ValueRef;
-
- pub fn LLVMBuildGEP(B: BuilderRef,
- Pointer: ValueRef,
- Indices: *const ValueRef,
- NumIndices: c_uint,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildInBoundsGEP(B: BuilderRef,
- Pointer: ValueRef,
- Indices: *const ValueRef,
- NumIndices: c_uint,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildStructGEP(B: BuilderRef,
- Pointer: ValueRef,
- Idx: c_uint,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildGlobalString(B: BuilderRef,
- Str: *const c_char,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildGlobalStringPtr(B: BuilderRef,
- Str: *const c_char,
- Name: *const c_char)
- -> ValueRef;
-
- /* Casts */
- pub fn LLVMBuildTrunc(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildZExt(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildSExt(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildFPToUI(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildFPToSI(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildUIToFP(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildSIToFP(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildFPTrunc(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildFPExt(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildPtrToInt(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildIntToPtr(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildBitCast(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildZExtOrBitCast(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildSExtOrBitCast(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildTruncOrBitCast(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildCast(B: BuilderRef,
- Op: Opcode,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char) -> ValueRef;
- pub fn LLVMBuildPointerCast(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildIntCast(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildFPCast(B: BuilderRef,
- Val: ValueRef,
- DestTy: TypeRef,
- Name: *const c_char)
- -> ValueRef;
-
- /* Comparisons */
- pub fn LLVMBuildICmp(B: BuilderRef,
- Op: c_uint,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildFCmp(B: BuilderRef,
- Op: c_uint,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
-
- /* Miscellaneous instructions */
- pub fn LLVMBuildPhi(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildCall(B: BuilderRef,
- Fn: ValueRef,
- Args: *const ValueRef,
- NumArgs: c_uint,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildSelect(B: BuilderRef,
- If: ValueRef,
- Then: ValueRef,
- Else: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildVAArg(B: BuilderRef,
- list: ValueRef,
- Ty: TypeRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildExtractElement(B: BuilderRef,
- VecVal: ValueRef,
- Index: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildInsertElement(B: BuilderRef,
- VecVal: ValueRef,
- EltVal: ValueRef,
- Index: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildShuffleVector(B: BuilderRef,
- V1: ValueRef,
- V2: ValueRef,
- Mask: ValueRef,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildExtractValue(B: BuilderRef,
- AggVal: ValueRef,
- Index: c_uint,
- Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildInsertValue(B: BuilderRef,
- AggVal: ValueRef,
- EltVal: ValueRef,
- Index: c_uint,
- Name: *const c_char)
- -> ValueRef;
-
- pub fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *const c_char)
- -> ValueRef;
- pub fn LLVMBuildPtrDiff(B: BuilderRef,
- LHS: ValueRef,
- RHS: ValueRef,
- Name: *const c_char)
- -> ValueRef;
-
- /* Atomic Operations */
- pub fn LLVMBuildAtomicLoad(B: BuilderRef,
- PointerVal: ValueRef,
- Name: *const c_char,
- Order: AtomicOrdering,
- Alignment: c_uint)
- -> ValueRef;
-
- pub fn LLVMBuildAtomicStore(B: BuilderRef,
- Val: ValueRef,
- Ptr: ValueRef,
- Order: AtomicOrdering,
- Alignment: c_uint)
- -> ValueRef;
-
- pub fn LLVMBuildAtomicCmpXchg(B: BuilderRef,
- LHS: ValueRef,
- CMP: ValueRef,
- RHS: ValueRef,
- Order: AtomicOrdering,
- FailureOrder: AtomicOrdering)
- -> ValueRef;
- pub fn LLVMBuildAtomicRMW(B: BuilderRef,
- Op: AtomicBinOp,
- LHS: ValueRef,
- RHS: ValueRef,
- Order: AtomicOrdering,
- SingleThreaded: Bool)
- -> ValueRef;
-
- pub fn LLVMBuildAtomicFence(B: BuilderRef, Order: AtomicOrdering);
-
-
- /* Selected entries from the downcasts. */
- pub fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef;
- pub fn LLVMIsAStoreInst(Inst: ValueRef) -> ValueRef;
-
- /** Writes a module to the specified path. Returns 0 on success. */
- pub fn LLVMWriteBitcodeToFile(M: ModuleRef, Path: *const c_char) -> c_int;
-
- /** Creates target data from a target layout string. */
- pub fn LLVMCreateTargetData(StringRep: *const c_char) -> TargetDataRef;
- /// Adds the target data to the given pass manager. The pass manager
- /// references the target data only weakly.
- pub fn LLVMAddTargetData(TD: TargetDataRef, PM: PassManagerRef);
- /** Number of bytes clobbered when doing a Store to *T. */
- pub fn LLVMStoreSizeOfType(TD: TargetDataRef, Ty: TypeRef)
- -> c_ulonglong;
-
- /** Number of bytes clobbered when doing a Store to *T. */
- pub fn LLVMSizeOfTypeInBits(TD: TargetDataRef, Ty: TypeRef)
- -> c_ulonglong;
-
- /** Distance between successive elements in an array of T.
- Includes ABI padding. */
- pub fn LLVMABISizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_uint;
-
- /** Returns the preferred alignment of a type. */
- pub fn LLVMPreferredAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
- -> c_uint;
- /** Returns the minimum alignment of a type. */
- pub fn LLVMABIAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
- -> c_uint;
-
- /// Computes the byte offset of the indexed struct element for a
- /// target.
- pub fn LLVMOffsetOfElement(TD: TargetDataRef,
- StructTy: TypeRef,
- Element: c_uint)
- -> c_ulonglong;
-
- /**
- * Returns the minimum alignment of a type when part of a call frame.
- */
- pub fn LLVMCallFrameAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
- -> c_uint;
-
- /** Disposes target data. */
- pub fn LLVMDisposeTargetData(TD: TargetDataRef);
-
- /** Creates a pass manager. */
- pub fn LLVMCreatePassManager() -> PassManagerRef;
-
- /** Creates a function-by-function pass manager */
- pub fn LLVMCreateFunctionPassManagerForModule(M: ModuleRef)
- -> PassManagerRef;
-
- /** Disposes a pass manager. */
- pub fn LLVMDisposePassManager(PM: PassManagerRef);
-
- /** Runs a pass manager on a module. */
- pub fn LLVMRunPassManager(PM: PassManagerRef, M: ModuleRef) -> Bool;
-
- /** Runs the function passes on the provided function. */
- pub fn LLVMRunFunctionPassManager(FPM: PassManagerRef, F: ValueRef)
- -> Bool;
-
- /** Initializes all the function passes scheduled in the manager */
- pub fn LLVMInitializeFunctionPassManager(FPM: PassManagerRef) -> Bool;
-
- /** Finalizes all the function passes scheduled in the manager */
- pub fn LLVMFinalizeFunctionPassManager(FPM: PassManagerRef) -> Bool;
-
- pub fn LLVMInitializePasses();
-
- /** Adds a verification pass. */
- pub fn LLVMAddVerifierPass(PM: PassManagerRef);
-
- pub fn LLVMAddGlobalOptimizerPass(PM: PassManagerRef);
- pub fn LLVMAddIPSCCPPass(PM: PassManagerRef);
- pub fn LLVMAddDeadArgEliminationPass(PM: PassManagerRef);
- pub fn LLVMAddInstructionCombiningPass(PM: PassManagerRef);
- pub fn LLVMAddCFGSimplificationPass(PM: PassManagerRef);
- pub fn LLVMAddFunctionInliningPass(PM: PassManagerRef);
- pub fn LLVMAddFunctionAttrsPass(PM: PassManagerRef);
- pub fn LLVMAddScalarReplAggregatesPass(PM: PassManagerRef);
- pub fn LLVMAddScalarReplAggregatesPassSSA(PM: PassManagerRef);
- pub fn LLVMAddJumpThreadingPass(PM: PassManagerRef);
- pub fn LLVMAddConstantPropagationPass(PM: PassManagerRef);
- pub fn LLVMAddReassociatePass(PM: PassManagerRef);
- pub fn LLVMAddLoopRotatePass(PM: PassManagerRef);
- pub fn LLVMAddLICMPass(PM: PassManagerRef);
- pub fn LLVMAddLoopUnswitchPass(PM: PassManagerRef);
- pub fn LLVMAddLoopDeletionPass(PM: PassManagerRef);
- pub fn LLVMAddLoopUnrollPass(PM: PassManagerRef);
- pub fn LLVMAddGVNPass(PM: PassManagerRef);
- pub fn LLVMAddMemCpyOptPass(PM: PassManagerRef);
- pub fn LLVMAddSCCPPass(PM: PassManagerRef);
- pub fn LLVMAddDeadStoreEliminationPass(PM: PassManagerRef);
- pub fn LLVMAddStripDeadPrototypesPass(PM: PassManagerRef);
- pub fn LLVMAddConstantMergePass(PM: PassManagerRef);
- pub fn LLVMAddArgumentPromotionPass(PM: PassManagerRef);
- pub fn LLVMAddTailCallEliminationPass(PM: PassManagerRef);
- pub fn LLVMAddIndVarSimplifyPass(PM: PassManagerRef);
- pub fn LLVMAddAggressiveDCEPass(PM: PassManagerRef);
- pub fn LLVMAddGlobalDCEPass(PM: PassManagerRef);
- pub fn LLVMAddCorrelatedValuePropagationPass(PM: PassManagerRef);
- pub fn LLVMAddPruneEHPass(PM: PassManagerRef);
- pub fn LLVMAddSimplifyLibCallsPass(PM: PassManagerRef);
- pub fn LLVMAddLoopIdiomPass(PM: PassManagerRef);
- pub fn LLVMAddEarlyCSEPass(PM: PassManagerRef);
- pub fn LLVMAddTypeBasedAliasAnalysisPass(PM: PassManagerRef);
- pub fn LLVMAddBasicAliasAnalysisPass(PM: PassManagerRef);
-
- pub fn LLVMPassManagerBuilderCreate() -> PassManagerBuilderRef;
- pub fn LLVMPassManagerBuilderDispose(PMB: PassManagerBuilderRef);
- pub fn LLVMPassManagerBuilderSetOptLevel(PMB: PassManagerBuilderRef,
- OptimizationLevel: c_uint);
- pub fn LLVMPassManagerBuilderSetSizeLevel(PMB: PassManagerBuilderRef,
- Value: Bool);
- pub fn LLVMPassManagerBuilderSetDisableUnitAtATime(
- PMB: PassManagerBuilderRef,
- Value: Bool);
- pub fn LLVMPassManagerBuilderSetDisableUnrollLoops(
- PMB: PassManagerBuilderRef,
- Value: Bool);
- pub fn LLVMPassManagerBuilderSetDisableSimplifyLibCalls(
- PMB: PassManagerBuilderRef,
- Value: Bool);
- pub fn LLVMPassManagerBuilderUseInlinerWithThreshold(
- PMB: PassManagerBuilderRef,
- threshold: c_uint);
- pub fn LLVMPassManagerBuilderPopulateModulePassManager(
- PMB: PassManagerBuilderRef,
- PM: PassManagerRef);
-
- pub fn LLVMPassManagerBuilderPopulateFunctionPassManager(
- PMB: PassManagerBuilderRef,
- PM: PassManagerRef);
- pub fn LLVMPassManagerBuilderPopulateLTOPassManager(
- PMB: PassManagerBuilderRef,
- PM: PassManagerRef,
- Internalize: Bool,
- RunInliner: Bool);
-
- /** Destroys a memory buffer. */
- pub fn LLVMDisposeMemoryBuffer(MemBuf: MemoryBufferRef);
-
-
- /* Stuff that's in rustllvm/ because it's not upstream yet. */
-
- /** Opens an object file. */
- pub fn LLVMCreateObjectFile(MemBuf: MemoryBufferRef) -> ObjectFileRef;
- /** Closes an object file. */
- pub fn LLVMDisposeObjectFile(ObjFile: ObjectFileRef);
-
- /** Enumerates the sections in an object file. */
- pub fn LLVMGetSections(ObjFile: ObjectFileRef) -> SectionIteratorRef;
- /** Destroys a section iterator. */
- pub fn LLVMDisposeSectionIterator(SI: SectionIteratorRef);
- /** Returns true if the section iterator is at the end of the section
- list: */
- pub fn LLVMIsSectionIteratorAtEnd(ObjFile: ObjectFileRef,
- SI: SectionIteratorRef)
- -> Bool;
- /** Moves the section iterator to point to the next section. */
- pub fn LLVMMoveToNextSection(SI: SectionIteratorRef);
- /** Returns the current section size. */
- pub fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong;
- /** Returns the current section contents as a string buffer. */
- pub fn LLVMGetSectionContents(SI: SectionIteratorRef) -> *const c_char;
-
- /** Reads the given file and returns it as a memory buffer. Use
- LLVMDisposeMemoryBuffer() to get rid of it. */
- pub fn LLVMRustCreateMemoryBufferWithContentsOfFile(Path: *const c_char)
- -> MemoryBufferRef;
- /** Borrows the contents of the memory buffer (doesn't copy it) */
- pub fn LLVMCreateMemoryBufferWithMemoryRange(InputData: *const c_char,
- InputDataLength: size_t,
- BufferName: *const c_char,
- RequiresNull: Bool)
- -> MemoryBufferRef;
- pub fn LLVMCreateMemoryBufferWithMemoryRangeCopy(InputData: *const c_char,
- InputDataLength: size_t,
- BufferName: *const c_char)
- -> MemoryBufferRef;
-
- pub fn LLVMIsMultithreaded() -> Bool;
- pub fn LLVMStartMultithreaded() -> Bool;
-
- /** Returns a string describing the last error caused by an LLVMRust*
- call. */
- pub fn LLVMRustGetLastError() -> *const c_char;
-
- /// Print the pass timings since static dtors aren't picking them up.
- pub fn LLVMRustPrintPassTimings();
-
- pub fn LLVMStructCreateNamed(C: ContextRef, Name: *const c_char) -> TypeRef;
-
- pub fn LLVMStructSetBody(StructTy: TypeRef,
- ElementTypes: *const TypeRef,
- ElementCount: c_uint,
- Packed: Bool);
-
- pub fn LLVMConstNamedStruct(S: TypeRef,
- ConstantVals: *const ValueRef,
- Count: c_uint)
- -> ValueRef;
-
- /** Enables LLVM debug output. */
- pub fn LLVMSetDebug(Enabled: c_int);
-
- /** Prepares inline assembly. */
- pub fn LLVMInlineAsm(Ty: TypeRef,
- AsmString: *const c_char,
- Constraints: *const c_char,
- SideEffects: Bool,
- AlignStack: Bool,
- Dialect: c_uint)
- -> ValueRef;
-
- pub static LLVMRustDebugMetadataVersion: u32;
-
- pub fn LLVMRustAddModuleFlag(M: ModuleRef,
- name: *const c_char,
- value: u32);
-
- pub fn LLVMDIBuilderCreate(M: ModuleRef) -> DIBuilderRef;
-
- pub fn LLVMDIBuilderDispose(Builder: DIBuilderRef);
-
- pub fn LLVMDIBuilderFinalize(Builder: DIBuilderRef);
-
- pub fn LLVMDIBuilderCreateCompileUnit(Builder: DIBuilderRef,
- Lang: c_uint,
- File: *const c_char,
- Dir: *const c_char,
- Producer: *const c_char,
- isOptimized: bool,
- Flags: *const c_char,
- RuntimeVer: c_uint,
- SplitName: *const c_char);
-
- pub fn LLVMDIBuilderCreateFile(Builder: DIBuilderRef,
- Filename: *const c_char,
- Directory: *const c_char)
- -> DIFile;
-
- pub fn LLVMDIBuilderCreateSubroutineType(Builder: DIBuilderRef,
- File: DIFile,
- ParameterTypes: DIArray)
- -> DICompositeType;
-
- pub fn LLVMDIBuilderCreateFunction(Builder: DIBuilderRef,
- Scope: DIDescriptor,
- Name: *const c_char,
- LinkageName: *const c_char,
- File: DIFile,
- LineNo: c_uint,
- Ty: DIType,
- isLocalToUnit: bool,
- isDefinition: bool,
- ScopeLine: c_uint,
- Flags: c_uint,
- isOptimized: bool,
- Fn: ValueRef,
- TParam: ValueRef,
- Decl: ValueRef)
- -> DISubprogram;
-
- pub fn LLVMDIBuilderCreateBasicType(Builder: DIBuilderRef,
- Name: *const c_char,
- SizeInBits: c_ulonglong,
- AlignInBits: c_ulonglong,
- Encoding: c_uint)
- -> DIBasicType;
-
- pub fn LLVMDIBuilderCreatePointerType(Builder: DIBuilderRef,
- PointeeTy: DIType,
- SizeInBits: c_ulonglong,
- AlignInBits: c_ulonglong,
- Name: *const c_char)
- -> DIDerivedType;
-
- pub fn LLVMDIBuilderCreateStructType(Builder: DIBuilderRef,
- Scope: DIDescriptor,
- Name: *const c_char,
- File: DIFile,
- LineNumber: c_uint,
- SizeInBits: c_ulonglong,
- AlignInBits: c_ulonglong,
- Flags: c_uint,
- DerivedFrom: DIType,
- Elements: DIArray,
- RunTimeLang: c_uint,
- VTableHolder: ValueRef,
- UniqueId: *const c_char)
- -> DICompositeType;
-
- pub fn LLVMDIBuilderCreateMemberType(Builder: DIBuilderRef,
- Scope: DIDescriptor,
- Name: *const c_char,
- File: DIFile,
- LineNo: c_uint,
- SizeInBits: c_ulonglong,
- AlignInBits: c_ulonglong,
- OffsetInBits: c_ulonglong,
- Flags: c_uint,
- Ty: DIType)
- -> DIDerivedType;
-
- pub fn LLVMDIBuilderCreateLexicalBlock(Builder: DIBuilderRef,
- Scope: DIDescriptor,
- File: DIFile,
- Line: c_uint,
- Col: c_uint,
- Discriminator: c_uint)
- -> DILexicalBlock;
-
- pub fn LLVMDIBuilderCreateStaticVariable(Builder: DIBuilderRef,
- Context: DIDescriptor,
- Name: *const c_char,
- LinkageName: *const c_char,
- File: DIFile,
- LineNo: c_uint,
- Ty: DIType,
- isLocalToUnit: bool,
- Val: ValueRef,
- Decl: ValueRef)
- -> DIGlobalVariable;
-
- pub fn LLVMDIBuilderCreateLocalVariable(Builder: DIBuilderRef,
- Tag: c_uint,
- Scope: DIDescriptor,
- Name: *const c_char,
- File: DIFile,
- LineNo: c_uint,
- Ty: DIType,
- AlwaysPreserve: bool,
- Flags: c_uint,
- ArgNo: c_uint)
- -> DIVariable;
-
- pub fn LLVMDIBuilderCreateArrayType(Builder: DIBuilderRef,
- Size: c_ulonglong,
- AlignInBits: c_ulonglong,
- Ty: DIType,
- Subscripts: DIArray)
- -> DIType;
-
- pub fn LLVMDIBuilderCreateVectorType(Builder: DIBuilderRef,
- Size: c_ulonglong,
- AlignInBits: c_ulonglong,
- Ty: DIType,
- Subscripts: DIArray)
- -> DIType;
-
- pub fn LLVMDIBuilderGetOrCreateSubrange(Builder: DIBuilderRef,
- Lo: c_longlong,
- Count: c_longlong)
- -> DISubrange;
-
- pub fn LLVMDIBuilderGetOrCreateArray(Builder: DIBuilderRef,
- Ptr: *const DIDescriptor,
- Count: c_uint)
- -> DIArray;
-
- pub fn LLVMDIBuilderInsertDeclareAtEnd(Builder: DIBuilderRef,
- Val: ValueRef,
- VarInfo: DIVariable,
- InsertAtEnd: BasicBlockRef)
- -> ValueRef;
-
- pub fn LLVMDIBuilderInsertDeclareBefore(Builder: DIBuilderRef,
- Val: ValueRef,
- VarInfo: DIVariable,
- InsertBefore: ValueRef)
- -> ValueRef;
-
- pub fn LLVMDIBuilderCreateEnumerator(Builder: DIBuilderRef,
- Name: *const c_char,
- Val: c_ulonglong)
- -> ValueRef;
-
- pub fn LLVMDIBuilderCreateEnumerationType(Builder: DIBuilderRef,
- Scope: ValueRef,
- Name: *const c_char,
- File: ValueRef,
- LineNumber: c_uint,
- SizeInBits: c_ulonglong,
- AlignInBits: c_ulonglong,
- Elements: ValueRef,
- ClassType: ValueRef)
- -> ValueRef;
-
- pub fn LLVMDIBuilderCreateUnionType(Builder: DIBuilderRef,
- Scope: ValueRef,
- Name: *const c_char,
- File: ValueRef,
- LineNumber: c_uint,
- SizeInBits: c_ulonglong,
- AlignInBits: c_ulonglong,
- Flags: c_uint,
- Elements: ValueRef,
- RunTimeLang: c_uint,
- UniqueId: *const c_char)
- -> ValueRef;
-
- pub fn LLVMSetUnnamedAddr(GlobalVar: ValueRef, UnnamedAddr: Bool);
-
- pub fn LLVMDIBuilderCreateTemplateTypeParameter(Builder: DIBuilderRef,
- Scope: ValueRef,
- Name: *const c_char,
- Ty: ValueRef,
- File: ValueRef,
- LineNo: c_uint,
- ColumnNo: c_uint)
- -> ValueRef;
-
- pub fn LLVMDIBuilderCreateOpDeref(IntType: TypeRef) -> ValueRef;
-
- pub fn LLVMDIBuilderCreateOpPlus(IntType: TypeRef) -> ValueRef;
-
- pub fn LLVMDIBuilderCreateComplexVariable(Builder: DIBuilderRef,
- Tag: c_uint,
- Scope: ValueRef,
- Name: *const c_char,
- File: ValueRef,
- LineNo: c_uint,
- Ty: ValueRef,
- AddrOps: *const ValueRef,
- AddrOpsCount: c_uint,
- ArgNo: c_uint)
- -> ValueRef;
-
- pub fn LLVMDIBuilderCreateNameSpace(Builder: DIBuilderRef,
- Scope: ValueRef,
- Name: *const c_char,
- File: ValueRef,
- LineNo: c_uint)
- -> ValueRef;
-
- pub fn LLVMDICompositeTypeSetTypeArray(CompositeType: ValueRef, TypeArray: ValueRef);
- pub fn LLVMTypeToString(Type: TypeRef) -> *const c_char;
- pub fn LLVMValueToString(value_ref: ValueRef) -> *const c_char;
-
- pub fn LLVMIsAArgument(value_ref: ValueRef) -> ValueRef;
-
- pub fn LLVMIsAAllocaInst(value_ref: ValueRef) -> ValueRef;
-
- pub fn LLVMInitializeX86TargetInfo();
- pub fn LLVMInitializeX86Target();
- pub fn LLVMInitializeX86TargetMC();
- pub fn LLVMInitializeX86AsmPrinter();
- pub fn LLVMInitializeX86AsmParser();
- pub fn LLVMInitializeARMTargetInfo();
- pub fn LLVMInitializeARMTarget();
- pub fn LLVMInitializeARMTargetMC();
- pub fn LLVMInitializeARMAsmPrinter();
- pub fn LLVMInitializeARMAsmParser();
- pub fn LLVMInitializeMipsTargetInfo();
- pub fn LLVMInitializeMipsTarget();
- pub fn LLVMInitializeMipsTargetMC();
- pub fn LLVMInitializeMipsAsmPrinter();
- pub fn LLVMInitializeMipsAsmParser();
-
- pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: *const c_char) -> bool;
- pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
- CPU: *const c_char,
- Features: *const c_char,
- Model: CodeGenModel,
- Reloc: RelocMode,
- Level: CodeGenOptLevel,
- EnableSegstk: bool,
- UseSoftFP: bool,
- NoFramePointerElim: bool,
- FunctionSections: bool,
- DataSections: bool) -> TargetMachineRef;
- pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef);
- pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef,
- PM: PassManagerRef,
- M: ModuleRef);
- pub fn LLVMRustAddBuilderLibraryInfo(PMB: PassManagerBuilderRef,
- M: ModuleRef,
- DisableSimplifyLibCalls: bool);
- pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef, M: ModuleRef,
- DisableSimplifyLibCalls: bool);
- pub fn LLVMRustRunFunctionPassManager(PM: PassManagerRef, M: ModuleRef);
- pub fn LLVMRustWriteOutputFile(T: TargetMachineRef,
- PM: PassManagerRef,
- M: ModuleRef,
- Output: *const c_char,
- FileType: FileType) -> bool;
- pub fn LLVMRustPrintModule(PM: PassManagerRef,
- M: ModuleRef,
- Output: *const c_char);
- pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char);
- pub fn LLVMRustPrintPasses();
- pub fn LLVMRustSetNormalizedTarget(M: ModuleRef, triple: *const c_char);
- pub fn LLVMRustAddAlwaysInlinePass(P: PassManagerBuilderRef,
- AddLifetimes: bool);
- pub fn LLVMRustLinkInExternalBitcode(M: ModuleRef,
- bc: *const c_char,
- len: size_t) -> bool;
- pub fn LLVMRustRunRestrictionPass(M: ModuleRef,
- syms: *const *const c_char,
- len: size_t);
- pub fn LLVMRustMarkAllFunctionsNounwind(M: ModuleRef);
-
- pub fn LLVMRustOpenArchive(path: *const c_char) -> ArchiveRef;
- pub fn LLVMRustArchiveReadSection(AR: ArchiveRef, name: *const c_char,
- out_len: *mut size_t) -> *const c_char;
- pub fn LLVMRustDestroyArchive(AR: ArchiveRef);
-
- pub fn LLVMRustSetDLLExportStorageClass(V: ValueRef);
- pub fn LLVMVersionMajor() -> c_int;
- pub fn LLVMVersionMinor() -> c_int;
-
- pub fn LLVMRustGetSectionName(SI: SectionIteratorRef,
- data: *mut *const c_char) -> c_int;
- }
-}
-
-pub fn SetInstructionCallConv(instr: ValueRef, cc: CallConv) {
- unsafe {
- llvm::LLVMSetInstructionCallConv(instr, cc as c_uint);
- }
-}
-pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) {
- unsafe {
- llvm::LLVMSetFunctionCallConv(fn_, cc as c_uint);
- }
-}
-pub fn SetLinkage(global: ValueRef, link: Linkage) {
- unsafe {
- llvm::LLVMSetLinkage(global, link as c_uint);
- }
-}
-
-pub fn SetUnnamedAddr(global: ValueRef, unnamed: bool) {
- unsafe {
- llvm::LLVMSetUnnamedAddr(global, unnamed as Bool);
- }
-}
-
-pub fn set_thread_local(global: ValueRef, is_thread_local: bool) {
- unsafe {
- llvm::LLVMSetThreadLocal(global, is_thread_local as Bool);
- }
-}
-
-pub fn ConstICmp(pred: IntPredicate, v1: ValueRef, v2: ValueRef) -> ValueRef {
- unsafe {
- llvm::LLVMConstICmp(pred as c_ushort, v1, v2)
- }
-}
-pub fn ConstFCmp(pred: RealPredicate, v1: ValueRef, v2: ValueRef) -> ValueRef {
- unsafe {
- llvm::LLVMConstFCmp(pred as c_ushort, v1, v2)
- }
-}
-
-pub fn SetFunctionAttribute(fn_: ValueRef, attr: Attribute) {
- unsafe {
- llvm::LLVMAddFunctionAttribute(fn_, FunctionIndex as c_uint, attr as uint64_t)
- }
-}
-/* Memory-managed object interface to type handles. */
-
-pub struct TypeNames {
- named_types: RefCell<HashMap<String, TypeRef>>,
-}
-
-impl TypeNames {
- pub fn new() -> TypeNames {
- TypeNames {
- named_types: RefCell::new(HashMap::new())
- }
- }
-
- pub fn associate_type(&self, s: &str, t: &Type) {
- assert!(self.named_types.borrow_mut().insert(s.to_string(),
- t.to_ref()));
- }
-
- pub fn find_type(&self, s: &str) -> Option<Type> {
- self.named_types.borrow().find_equiv(&s).map(|x| Type::from_ref(*x))
- }
-
- pub fn type_to_str(&self, ty: Type) -> String {
- unsafe {
- let s = llvm::LLVMTypeToString(ty.to_ref());
- let ret = from_c_str(s);
- free(s as *mut c_void);
- ret.to_string()
- }
- }
-
- pub fn types_to_str(&self, tys: &[Type]) -> String {
- let strs: Vec<String> = tys.iter().map(|t| self.type_to_str(*t)).collect();
- format!("[{}]", strs.connect(","))
- }
-
- pub fn val_to_str(&self, val: ValueRef) -> String {
- unsafe {
- let s = llvm::LLVMValueToString(val);
- let ret = from_c_str(s);
- free(s as *mut c_void);
- ret.to_string()
- }
- }
-}
-
-/* Memory-managed interface to target data. */
-
-pub struct TargetData {
- pub lltd: TargetDataRef
-}
-
-impl Drop for TargetData {
- fn drop(&mut self) {
- unsafe {
- llvm::LLVMDisposeTargetData(self.lltd);
- }
- }
-}
-
-pub fn mk_target_data(string_rep: &str) -> TargetData {
- TargetData {
- lltd: string_rep.with_c_str(|buf| {
- unsafe { llvm::LLVMCreateTargetData(buf) }
- })
- }
-}
-
-/* Memory-managed interface to object files. */
-
-pub struct ObjectFile {
- pub llof: ObjectFileRef,
-}
-
-impl ObjectFile {
- // This will take ownership of llmb
- pub fn new(llmb: MemoryBufferRef) -> Option<ObjectFile> {
- unsafe {
- let llof = llvm::LLVMCreateObjectFile(llmb);
- if llof as int == 0 {
- // LLVMCreateObjectFile took ownership of llmb
- return None
- }
-
- Some(ObjectFile {
- llof: llof,
- })
- }
- }
-}
-
-impl Drop for ObjectFile {
- fn drop(&mut self) {
- unsafe {
- llvm::LLVMDisposeObjectFile(self.llof);
- }
- }
-}
-
-/* Memory-managed interface to section iterators. */
-
-pub struct SectionIter {
- pub llsi: SectionIteratorRef
-}
-
-impl Drop for SectionIter {
- fn drop(&mut self) {
- unsafe {
- llvm::LLVMDisposeSectionIterator(self.llsi);
- }
- }
-}
-
-pub fn mk_section_iter(llof: ObjectFileRef) -> SectionIter {
- unsafe {
- SectionIter {
- llsi: llvm::LLVMGetSections(llof)
- }
- }
-}
--- /dev/null
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// WARNING: THIS IS A GENERATED FILE, DO NOT MODIFY
+// take a look at src/etc/mklldeps.py if you're interested
+
+#[cfg(target_arch = "x86_64", target_os = "linux")]
+#[link(name = "LLVMInstrumentation", kind = "static")]
+#[link(name = "LLVMInterpreter", kind = "static")]
+#[link(name = "LLVMMCJIT", kind = "static")]
+#[link(name = "LLVMRuntimeDyld", kind = "static")]
+#[link(name = "LLVMJIT", kind = "static")]
+#[link(name = "LLVMExecutionEngine", kind = "static")]
+#[link(name = "LLVMAsmParser", kind = "static")]
+#[link(name = "LLVMLinker", kind = "static")]
+#[link(name = "LLVMBitWriter", kind = "static")]
+#[link(name = "LLVMipo", kind = "static")]
+#[link(name = "LLVMVectorize", kind = "static")]
+#[link(name = "LLVMMipsDisassembler", kind = "static")]
+#[link(name = "LLVMMipsCodeGen", kind = "static")]
+#[link(name = "LLVMMipsAsmParser", kind = "static")]
+#[link(name = "LLVMMipsDesc", kind = "static")]
+#[link(name = "LLVMMipsInfo", kind = "static")]
+#[link(name = "LLVMMipsAsmPrinter", kind = "static")]
+#[link(name = "LLVMARMDisassembler", kind = "static")]
+#[link(name = "LLVMARMCodeGen", kind = "static")]
+#[link(name = "LLVMARMAsmParser", kind = "static")]
+#[link(name = "LLVMARMDesc", kind = "static")]
+#[link(name = "LLVMARMInfo", kind = "static")]
+#[link(name = "LLVMARMAsmPrinter", kind = "static")]
+#[link(name = "LLVMX86Disassembler", kind = "static")]
+#[link(name = "LLVMX86AsmParser", kind = "static")]
+#[link(name = "LLVMX86CodeGen", kind = "static")]
+#[link(name = "LLVMSelectionDAG", kind = "static")]
+#[link(name = "LLVMAsmPrinter", kind = "static")]
+#[link(name = "LLVMMCParser", kind = "static")]
+#[link(name = "LLVMCodeGen", kind = "static")]
+#[link(name = "LLVMScalarOpts", kind = "static")]
+#[link(name = "LLVMInstCombine", kind = "static")]
+#[link(name = "LLVMTransformUtils", kind = "static")]
+#[link(name = "LLVMipa", kind = "static")]
+#[link(name = "LLVMAnalysis", kind = "static")]
+#[link(name = "LLVMTarget", kind = "static")]
+#[link(name = "LLVMX86Desc", kind = "static")]
+#[link(name = "LLVMX86Info", kind = "static")]
+#[link(name = "LLVMX86AsmPrinter", kind = "static")]
+#[link(name = "LLVMMC", kind = "static")]
+#[link(name = "LLVMObject", kind = "static")]
+#[link(name = "LLVMBitReader", kind = "static")]
+#[link(name = "LLVMCore", kind = "static")]
+#[link(name = "LLVMX86Utils", kind = "static")]
+#[link(name = "LLVMSupport", kind = "static")]
+#[link(name = "pthread")]
+#[link(name = "dl")]
+#[link(name = "m")]
+#[link(name = "stdc++")]
+extern {}
use middle::typeck::astconv::ast_ty_to_ty;
use middle::typeck::infer;
use middle::{typeck, ty, def, pat_util, stability};
-use util::ppaux::{ty_to_str};
+use util::ppaux::{ty_to_string};
use util::nodemap::NodeSet;
use lint::{Context, LintPass, LintArray};
use std::cmp;
use std::collections::HashMap;
-use std::i16;
-use std::i32;
-use std::i64;
-use std::i8;
-use std::u16;
-use std::u32;
-use std::u64;
-use std::u8;
+use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
use std::gc::Gc;
use syntax::abi;
use syntax::ast_map;
"literal out of range for its type");
}
},
-
+ ty::ty_float(t) => {
+ let (min, max) = float_ty_range(t);
+ let lit_val: f64 = match lit.node {
+ ast::LitFloat(ref v, _) |
+ ast::LitFloatUnsuffixed(ref v) => match from_str(v.get()) {
+ Some(f) => f,
+ None => return
+ },
+ _ => fail!()
+ };
+ if lit_val < min || lit_val > max {
+ cx.span_lint(TYPE_OVERFLOW, e.span,
+ "literal out of range for its type");
+ }
+ },
_ => ()
};
},
}
}
+ fn float_ty_range(float_ty: ast::FloatTy) -> (f64, f64) {
+ match float_ty {
+ ast::TyF32 => (f32::MIN_VALUE as f64, f32::MAX_VALUE as f64),
+ ast::TyF64 => (f64::MIN_VALUE, f64::MAX_VALUE)
+ }
+ }
+
fn check_limits(tcx: &ty::ctxt, binop: ast::BinOp,
l: &ast::Expr, r: &ast::Expr) -> bool {
let (lit, expr, swap) = match (&l.node, &r.node) {
});
if n_uniq > 0 {
- let s = ty_to_str(cx.tcx, ty);
+ let s = ty_to_string(cx.tcx, ty);
let m = format!("type uses owned (Box type) pointers: {}", s);
cx.span_lint(OWNED_HEAP_MEMORY, span, m.as_slice());
cx.span_lint(HEAP_MEMORY, span, m.as_slice());
}
if n_box > 0 {
- let s = ty_to_str(cx.tcx, ty);
+ let s = ty_to_string(cx.tcx, ty);
let m = format!("type uses managed (@ type) pointers: {}", s);
cx.span_lint(MANAGED_HEAP_MEMORY, span, m.as_slice());
cx.span_lint(HEAP_MEMORY, span, m.as_slice());
}
fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) {
- static ATTRIBUTE_WHITELIST: &'static [&'static str] = &'static [
+ static ATTRIBUTE_WHITELIST: &'static [&'static str] = &[
// FIXME: #14408 whitelist docs since rustdoc looks at them
"doc",
"unstable",
];
- static CRATE_ATTRS: &'static [&'static str] = &'static [
+ static CRATE_ATTRS: &'static [&'static str] = &[
+ "crate_name",
"crate_type",
"feature",
"no_start",
"no_main",
"no_std",
- "crate_id",
"desc",
"comment",
"license",
if ast_util::is_local(did) {
match cx.tcx.map.get(did.node) {
ast_map::NodeItem(it) => {
- if attr::contains_name(it.attrs.as_slice(),
- "must_use") {
- cx.span_lint(UNUSED_MUST_USE, s.span,
- "unused result which must be used");
- warned = true;
- }
+ warned |= check_must_use(cx, it.attrs.as_slice(), s.span);
}
_ => {}
}
} else {
csearch::get_item_attrs(&cx.sess().cstore, did, |attrs| {
- if attr::contains_name(attrs.as_slice(), "must_use") {
- cx.span_lint(UNUSED_MUST_USE, s.span,
- "unused result which must be used");
- warned = true;
- }
+ warned |= check_must_use(cx, attrs.as_slice(), s.span);
});
}
}
if !warned {
cx.span_lint(UNUSED_RESULT, s.span, "unused result");
}
+
+ fn check_must_use(cx: &Context, attrs: &[ast::Attribute], sp: Span) -> bool {
+ for attr in attrs.iter() {
+ if attr.check_name("must_use") {
+ let mut msg = "unused result which must be used".to_string();
+ // check for #[must_use="..."]
+ match attr.value_str() {
+ None => {}
+ Some(s) => {
+ msg.push_str(": ");
+ msg.push_str(s.get());
+ }
+ }
+ cx.span_lint(UNUSED_MUST_USE, sp, msg.as_slice());
+ return true;
+ }
+ }
+ false
+ }
}
}
}
}
+ let has_extern_repr = it.attrs.iter().fold(attr::ReprAny, |acc, attr| {
+ attr::find_repr_attr(cx.tcx.sess.diagnostic(), attr, acc)
+ }) == attr::ReprExtern;
+ if has_extern_repr { return }
+
match it.node {
ast::ItemTy(..) | ast::ItemStruct(..) => {
check_case(cx, "type", it.ident, it.span)
match mode {
ast::BindByValue(ast::MutMutable) => {
if !token::get_ident(ident).get().starts_with("_") {
- mutables.insert_or_update_with(ident.name as uint,
+ mutables.insert_or_update_with(ident.name.uint(),
vec!(id), |_, old| { old.push(id); });
}
}
for &(lint, span, ref msg) in v.iter() {
tcx.sess.span_bug(span,
format!("unprocessed lint {} at {}: {}",
- lint.as_str(), tcx.map.node_to_str(*id), *msg).as_slice())
+ lint.as_str(), tcx.map.node_to_string(*id), *msg).as_slice())
}
}
#![allow(non_camel_case_types)]
use std::mem;
-use syntax::crateid::CrateId;
use back::svh::Svh;
// EBML enum definitions and utils shared by the encoder and decoder
pub static tag_crate_dep: uint = 0x19;
pub static tag_crate_hash: uint = 0x1a;
-pub static tag_crate_crateid: uint = 0x1b;
+pub static tag_crate_crate_name: uint = 0x1b;
-pub static tag_crate_dep_crateid: uint = 0x1d;
+pub static tag_crate_dep_crate_name: uint = 0x1d;
pub static tag_crate_dep_hash: uint = 0x1e;
pub static tag_mod_impl: uint = 0x1f;
#[deriving(Clone, Show)]
pub struct LinkMeta {
- pub crateid: CrateId,
+ pub crate_name: String,
pub crate_hash: Svh,
}
//! Validates all used crates and extern libraries and loads their metadata
-use back::link;
use back::svh::Svh;
use driver::session::Session;
use driver::{driver, config};
use syntax::diagnostic::SpanHandler;
use syntax::parse::token::InternedString;
use syntax::parse::token;
-use syntax::crateid::CrateId;
use syntax::visit;
struct Env<'a> {
fn dump_crates(cstore: &CStore) {
debug!("resolved crates:");
cstore.iter_crate_data_origins(|_, data, opt_source| {
- debug!("crate_id: {}", data.crate_id());
+ debug!(" name: {}", data.name());
debug!(" cnum: {}", data.cnum);
debug!(" hash: {}", data.hash());
opt_source.map(|cs| {
fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) {
let mut map = HashMap::new();
cstore.iter_crate_data(|cnum, data| {
- let crateid = data.crate_id();
- let key = (crateid.name.clone(), crateid.path.clone());
- map.find_or_insert_with(key, |_| Vec::new()).push(cnum);
+ map.find_or_insert_with(data.name(), |_| Vec::new()).push(cnum);
});
- for ((name, _), dupes) in map.move_iter() {
+ for (name, dupes) in map.move_iter() {
if dupes.len() == 1 { continue }
diag.handler().warn(
- format!("using multiple versions of crate `{}`",
- name).as_slice());
+ format!("using multiple versions of crate `{}`", name).as_slice());
for dupe in dupes.move_iter() {
let data = cstore.get_crate_data(dupe);
diag.span_note(data.span, "used here");
- loader::note_crateid_attr(diag, &data.crate_id());
+ loader::note_crate_name(diag, data.name().as_slice());
}
}
}
let (cnum, _, _) = resolve_crate(e,
&None,
info.ident.as_slice(),
- &info.crate_id,
+ info.name.as_slice(),
None,
i.span);
e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
struct CrateInfo {
ident: String,
- crate_id: CrateId,
+ name: String,
id: ast::NodeId,
should_link: bool,
}
let ident = token::get_ident(ident);
debug!("resolving extern crate stmt. ident: {:?} path_opt: {:?}",
ident, path_opt);
- let crate_id = match *path_opt {
+ let name = match *path_opt {
Some((ref path_str, _)) => {
- let crateid: Option<CrateId> = from_str(path_str.get());
- match crateid {
- None => {
- e.sess.span_err(i.span, "malformed crate id");
- return None
- }
- Some(id) => id
- }
+ let name = path_str.get().to_string();
+ validate_crate_name(Some(e.sess), name.as_slice(),
+ Some(i.span));
+ name
}
- None => from_str(ident.get().to_str().as_slice()).unwrap()
+ None => ident.get().to_string(),
};
Some(CrateInfo {
ident: ident.get().to_string(),
- crate_id: crate_id,
+ name: name,
id: id,
should_link: should_link(i),
})
}
}
+pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
+ let err = |s: &str| {
+ match (sp, sess) {
+ (_, None) => fail!("{}", s),
+ (Some(sp), Some(sess)) => sess.span_err(sp, s),
+ (None, Some(sess)) => sess.err(s),
+ }
+ };
+ if s.len() == 0 {
+ err("crate name must not be empty");
+ }
+ for c in s.chars() {
+ if c.is_alphanumeric() { continue }
+ if c == '_' || c == '-' { continue }
+ err(format!("invalid character `{}` in crate name: `{}`", c, s).as_slice());
+ }
+ match sess {
+ Some(sess) => sess.abort_if_errors(),
+ None => {}
+ }
+}
+
fn visit_item(e: &Env, i: &ast::Item) {
match i.node {
ast::ItemForeignMod(ref fm) => {
}
}
-fn existing_match(e: &Env, crate_id: &CrateId,
+fn existing_match(e: &Env, name: &str,
hash: Option<&Svh>) -> Option<ast::CrateNum> {
let mut ret = None;
e.sess.cstore.iter_crate_data(|cnum, data| {
- let other_id = data.crate_id();
- if crate_id.matches(&other_id) {
- let other_hash = data.hash();
- match hash {
- Some(hash) if *hash != other_hash => {}
- Some(..) | None => { ret = Some(cnum); }
+ if data.name().as_slice() != name { return }
+
+ match hash {
+ Some(hash) if *hash == data.hash() => { ret = Some(cnum); return }
+ Some(..) => return,
+ None => {}
+ }
+
+ // When the hash is None we're dealing with a top-level dependency in
+ // which case we may have a specification on the command line for this
+ // library. Even though an upstream library may have loaded something of
+ // the same name, we have to make sure it was loaded from the exact same
+ // location as well.
+ let source = e.sess.cstore.get_used_crate_source(cnum).unwrap();
+ let dylib = source.dylib.as_ref().map(|p| p.as_vec());
+ let rlib = source.rlib.as_ref().map(|p| p.as_vec());
+ match e.sess.opts.externs.find_equiv(&name) {
+ Some(locs) => {
+ let found = locs.iter().any(|l| {
+ Some(l.as_bytes()) == dylib || Some(l.as_bytes()) == rlib
+ });
+ if found {
+ ret = Some(cnum);
+ }
}
+ None => ret = Some(cnum),
}
});
return ret;
fn register_crate<'a>(e: &mut Env,
root: &Option<CratePaths>,
ident: &str,
- crate_id: &CrateId,
+ name: &str,
span: Span,
lib: loader::Library)
-> (ast::CrateNum, Rc<cstore::crate_metadata>,
let loader::Library{ dylib, rlib, metadata } = lib;
let cmeta = Rc::new( cstore::crate_metadata {
- name: crate_id.name.to_string(),
+ name: name.to_string(),
data: metadata,
cnum_map: cnum_map,
cnum: cnum,
fn resolve_crate<'a>(e: &mut Env,
root: &Option<CratePaths>,
ident: &str,
- crate_id: &CrateId,
+ name: &str,
hash: Option<&Svh>,
span: Span)
-> (ast::CrateNum, Rc<cstore::crate_metadata>,
cstore::CrateSource) {
- match existing_match(e, crate_id, hash) {
+ match existing_match(e, name, hash) {
None => {
- let id_hash = link::crate_id_hash(crate_id);
let mut load_ctxt = loader::Context {
sess: e.sess,
span: span,
ident: ident,
- crate_id: crate_id,
- id_hash: id_hash.as_slice(),
+ crate_name: name,
hash: hash.map(|a| &*a),
filesearch: e.sess.target_filesearch(),
os: e.sess.targ_cfg.os,
root: root,
rejected_via_hash: vec!(),
rejected_via_triple: vec!(),
+ should_match_name: true,
};
let library = load_ctxt.load_library_crate();
- register_crate(e, root, ident, crate_id, span, library)
+ register_crate(e, root, ident, name, span, library)
}
Some(cnum) => (cnum,
e.sess.cstore.get_crate_data(cnum),
// The map from crate numbers in the crate we're resolving to local crate
// numbers
decoder::get_crate_deps(cdata).iter().map(|dep| {
- debug!("resolving dep crate {} hash: `{}`", dep.crate_id, dep.hash);
+ debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
let (local_cnum, _, _) = resolve_crate(e, root,
- dep.crate_id.name.as_slice(),
- &dep.crate_id,
+ dep.name.as_slice(),
+ dep.name.as_slice(),
Some(&dep.hash),
span);
(dep.cnum, local_cnum)
let target_triple = self.env.sess.targ_cfg.target_strs.target_triple.as_slice();
let is_cross = target_triple != driver::host_triple();
let mut should_link = info.should_link && !is_cross;
- let id_hash = link::crate_id_hash(&info.crate_id);
let os = config::get_os(driver::host_triple()).unwrap();
let mut load_ctxt = loader::Context {
sess: self.env.sess,
span: krate.span,
ident: info.ident.as_slice(),
- crate_id: &info.crate_id,
- id_hash: id_hash.as_slice(),
+ crate_name: info.name.as_slice(),
hash: None,
filesearch: self.env.sess.host_filesearch(),
triple: driver::host_triple(),
root: &None,
rejected_via_hash: vec!(),
rejected_via_triple: vec!(),
+ should_match_name: true,
};
let library = match load_ctxt.maybe_load_library_crate() {
- Some (l) => l,
+ Some(l) => l,
None if is_cross => {
// try loading from target crates (only valid if there are
// no syntax extensions)
let registrar = decoder::get_plugin_registrar_fn(library.metadata.as_slice()).map(|id| {
decoder::get_symbol(library.metadata.as_slice(), id)
});
+ if library.dylib.is_none() && registrar.is_some() {
+ let message = format!("plugin crate `{}` only found in rlib format, \
+ but must be available in dylib format",
+ info.ident);
+ self.env.sess.span_err(krate.span, message.as_slice());
+ // No need to abort because the loading code will just ignore this
+ // empty dylib.
+ }
let pc = PluginMetadata {
lib: library.dylib.clone(),
macros: macros,
registrar_symbol: registrar,
};
- if should_link && existing_match(&self.env, &info.crate_id, None).is_none() {
+ if should_link && existing_match(&self.env, info.name.as_slice(),
+ None).is_none() {
// register crate now to avoid double-reading metadata
register_crate(&mut self.env, &None, info.ident.as_slice(),
- &info.crate_id, krate.span, library);
+ info.name.as_slice(), krate.span, library);
}
pc
}
use std::rc::Rc;
use std::collections::HashMap;
use syntax::ast;
-use syntax::crateid::CrateId;
use syntax::codemap::Span;
use syntax::parse::token::IdentInterner;
}
pub fn add_used_link_args(&self, args: &str) {
- for s in args.split(' ') {
+ for s in args.split(' ').filter(|s| !s.is_empty()) {
self.used_link_args.borrow_mut().push(s.to_string());
}
}
impl crate_metadata {
pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() }
- pub fn crate_id(&self) -> CrateId { decoder::get_crate_id(self.data()) }
+ pub fn name(&self) -> String { decoder::get_crate_name(self.data()) }
pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) }
}
use syntax::print::pprust;
use syntax::ast;
use syntax::codemap;
-use syntax::crateid::CrateId;
pub type Cmd<'a> = &'a crate_metadata;
}
}
-fn item_sized(item: ebml::Doc) -> ast::Sized {
- match reader::maybe_get_doc(item, tag_items_data_item_sized) {
- None => ast::StaticSize,
- Some(sized_doc) => {
- match reader::doc_as_u8(sized_doc) as char {
- 'd' => ast::DynSize,
- 's' => ast::StaticSize,
- _ => fail!("unknown sized-ness character")
- }
- }
- }
-}
-
fn item_method_sort(item: ebml::Doc) -> char {
let mut ret = 'r';
reader::tagged_docs(item, tag_item_trait_method_sort, |doc| {
let string = name.as_str_slice();
match intr.find_equiv(&string) {
None => token::str_to_ident(string),
- Some(val) => ast::Ident::new(val as ast::Name),
+ Some(val) => ast::Ident::new(val),
}
}
let tp_defs = item_ty_param_defs(item_doc, tcx, cdata,
tag_items_data_item_ty_param_bounds);
let rp_defs = item_region_param_defs(item_doc, cdata);
- let sized = item_sized(item_doc);
let mut bounds = ty::empty_builtin_bounds();
// Collect the builtin bounds from the encoded supertraits.
// FIXME(#8559): They should be encoded directly.
});
true
});
- // Turn sized into a bound, FIXME(#8559).
- if sized == ast::StaticSize {
- tcx.lang_items.to_builtin_kind(tcx.lang_items.sized_trait().unwrap()).map(|bound| {
- bounds.add(bound);
- });
- }
ty::TraitDef {
generics: ty::Generics {types: tp_defs,
let explicit_self_kind = string.as_bytes()[0];
match explicit_self_kind as char {
's' => ast::SelfStatic,
- 'v' => ast::SelfValue,
- '~' => ast::SelfUniq,
+ 'v' => ast::SelfValue(special_idents::self_),
+ '~' => ast::SelfUniq(special_idents::self_),
// FIXME(#4846) expl. region
- '&' => ast::SelfRegion(None, get_mutability(string.as_bytes()[1])),
+ '&' => ast::SelfRegion(None, get_mutability(string.as_bytes()[1]),
+ special_idents::self_),
_ => fail!("unknown self type code: `{}`", explicit_self_kind as char)
}
}
let r = get_attributes(md);
for attr in r.iter() {
- try!(write!(out, "{}\n", pprust::attribute_to_str(attr)));
+ try!(write!(out, "{}\n", pprust::attribute_to_string(attr)));
}
write!(out, "\n\n")
#[deriving(Clone)]
pub struct CrateDep {
pub cnum: ast::CrateNum,
- pub crate_id: CrateId,
+ pub name: String,
pub hash: Svh,
}
d.as_str_slice().to_string()
}
reader::tagged_docs(depsdoc, tag_crate_dep, |depdoc| {
- let crate_id =
- from_str(docstr(depdoc,
- tag_crate_dep_crateid).as_slice()).unwrap();
+ let name = docstr(depdoc, tag_crate_dep_crate_name);
let hash = Svh::new(docstr(depdoc, tag_crate_dep_hash).as_slice());
deps.push(CrateDep {
cnum: crate_num,
- crate_id: crate_id,
+ name: name,
hash: hash,
});
crate_num += 1;
fn list_crate_deps(data: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
try!(write!(out, "=External Dependencies=\n"));
for dep in get_crate_deps(data).iter() {
- try!(write!(out, "{} {}-{}\n", dep.cnum, dep.crate_id, dep.hash));
+ try!(write!(out, "{} {}-{}\n", dep.cnum, dep.name, dep.hash));
}
try!(write!(out, "\n"));
Ok(())
Svh::new(hashdoc.as_str_slice())
}
-pub fn maybe_get_crate_id(data: &[u8]) -> Option<CrateId> {
+pub fn maybe_get_crate_name(data: &[u8]) -> Option<String> {
let cratedoc = ebml::Doc::new(data);
- reader::maybe_get_doc(cratedoc, tag_crate_crateid).map(|doc| {
- from_str(doc.as_str_slice()).unwrap()
+ reader::maybe_get_doc(cratedoc, tag_crate_crate_name).map(|doc| {
+ doc.as_str_slice().to_string()
})
}
-pub fn get_crate_triple(data: &[u8]) -> String {
+pub fn get_crate_triple(data: &[u8]) -> Option<String> {
let cratedoc = ebml::Doc::new(data);
let triple_doc = reader::maybe_get_doc(cratedoc, tag_crate_triple);
- triple_doc.expect("No triple in crate").as_str().to_string()
+ triple_doc.map(|s| s.as_str().to_string())
}
-pub fn get_crate_id(data: &[u8]) -> CrateId {
- let cratedoc = ebml::Doc::new(data);
- let hashdoc = reader::get_doc(cratedoc, tag_crate_crateid);
- from_str(hashdoc.as_str_slice()).unwrap()
+pub fn get_crate_name(data: &[u8]) -> String {
+ maybe_get_crate_name(data).expect("no crate name in crate")
}
pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
use syntax::ast_map;
use syntax::ast_util::*;
use syntax::ast_util;
-use syntax::attr::AttrMetaMethods;
use syntax::attr;
-use syntax::crateid::CrateId;
+use syntax::attr::AttrMetaMethods;
use syntax::diagnostic::SpanHandler;
-use syntax::parse::token::InternedString;
use syntax::parse::token::special_idents;
use syntax::parse::token;
use syntax::visit::Visitor;
}
pub fn encode_def_id(ebml_w: &mut Encoder, id: DefId) {
- ebml_w.wr_tagged_str(tag_def_id, def_to_str(id).as_slice());
+ ebml_w.wr_tagged_str(tag_def_id, def_to_string(id).as_slice());
}
#[deriving(Clone)]
tag: uint) {
let ty_str_ctxt = &tyencode::ctxt {
diag: ecx.diag,
- ds: def_to_str,
+ ds: def_to_string,
tcx: ecx.tcx,
abbrevs: &ecx.type_abbrevs
};
ebml_w.end_tag();
}
-pub fn def_to_str(did: DefId) -> String {
+pub fn def_to_string(did: DefId) -> String {
format!("{}:{}", did.krate, did.node)
}
tag: uint) {
let ty_str_ctxt = &tyencode::ctxt {
diag: ecx.diag,
- ds: def_to_str,
+ ds: def_to_string,
tcx: ecx.tcx,
abbrevs: &ecx.type_abbrevs
};
ebml_w.end_tag();
ebml_w.wr_tagged_str(tag_region_param_def_def_id,
- def_to_str(param.def_id).as_slice());
+ def_to_string(param.def_id).as_slice());
ebml_w.wr_tagged_u64(tag_region_param_def_space,
param.space.to_uint() as u64);
fn encode_variant_id(ebml_w: &mut Encoder, vid: DefId) {
ebml_w.start_tag(tag_items_data_item_variant);
- let s = def_to_str(vid);
+ let s = def_to_string(vid);
ebml_w.writer.write(s.as_bytes());
ebml_w.end_tag();
}
typ: ty::t) {
let ty_str_ctxt = &tyencode::ctxt {
diag: ecx.diag,
- ds: def_to_str,
+ ds: def_to_string,
tcx: ecx.tcx,
abbrevs: &ecx.type_abbrevs
};
let ty_str_ctxt = &tyencode::ctxt {
diag: ecx.diag,
- ds: def_to_str,
+ ds: def_to_string,
tcx: ecx.tcx,
abbrevs: &ecx.type_abbrevs
};
ebml_w: &mut Encoder,
disr_val: ty::Disr) {
ebml_w.start_tag(tag_disr_val);
- let s = disr_val.to_str();
+ let s = disr_val.to_string();
ebml_w.writer.write(s.as_bytes());
ebml_w.end_tag();
}
fn encode_parent_item(ebml_w: &mut Encoder, id: DefId) {
ebml_w.start_tag(tag_items_data_parent_item);
- let s = def_to_str(id);
+ let s = def_to_string(id);
ebml_w.writer.write(s.as_bytes());
ebml_w.end_tag();
}
encode_struct_field_family(ebml_w, f.vis);
encode_def_id(ebml_w, f.id);
ebml_w.start_tag(tag_item_field_origin);
- let s = def_to_str(origin);
+ let s = def_to_string(origin);
ebml_w.writer.write(s.as_bytes());
ebml_w.end_tag();
ebml_w.end_tag();
exp.name, token::get_ident(method_ident));
ebml_w.start_tag(tag_items_data_item_reexport);
ebml_w.start_tag(tag_items_data_item_reexport_def_id);
- ebml_w.wr_str(def_to_str(method_def_id).as_slice());
+ ebml_w.wr_str(def_to_string(method_def_id).as_slice());
ebml_w.end_tag();
ebml_w.start_tag(tag_items_data_item_reexport_name);
ebml_w.wr_str(format!("{}::{}",
id);
ebml_w.start_tag(tag_items_data_item_reexport);
ebml_w.start_tag(tag_items_data_item_reexport_def_id);
- ebml_w.wr_str(def_to_str(exp.def_id).as_slice());
+ ebml_w.wr_str(def_to_string(exp.def_id).as_slice());
ebml_w.end_tag();
ebml_w.start_tag(tag_items_data_item_reexport_name);
ebml_w.wr_str(exp.name.as_slice());
// Encode info about all the module children.
for item in md.items.iter() {
ebml_w.start_tag(tag_mod_child);
- ebml_w.wr_str(def_to_str(local_def(item.id)).as_slice());
+ ebml_w.wr_str(def_to_string(local_def(item.id)).as_slice());
ebml_w.end_tag();
each_auxiliary_node_id(*item, |auxiliary_node_id| {
ebml_w.start_tag(tag_mod_child);
- ebml_w.wr_str(def_to_str(local_def(
+ ebml_w.wr_str(def_to_string(local_def(
auxiliary_node_id)).as_slice());
ebml_w.end_tag();
true
debug!("(encoding info for module) ... encoding impl {} \
({:?}/{:?})",
token::get_ident(ident),
- did, ecx.tcx.map.node_to_str(did));
+ did, ecx.tcx.map.node_to_string(did));
ebml_w.start_tag(tag_mod_impl);
- ebml_w.wr_str(def_to_str(local_def(did)).as_slice());
+ ebml_w.wr_str(def_to_string(local_def(did)).as_slice());
ebml_w.end_tag();
}
_ => {}
// Encode the base self type.
match explicit_self {
- SelfStatic => { ebml_w.writer.write(&[ 's' as u8 ]); }
- SelfValue => { ebml_w.writer.write(&[ 'v' as u8 ]); }
- SelfUniq => { ebml_w.writer.write(&[ '~' as u8 ]); }
- SelfRegion(_, m) => {
+ SelfStatic => { ebml_w.writer.write(&[ 's' as u8 ]); }
+ SelfValue(_) => { ebml_w.writer.write(&[ 'v' as u8 ]); }
+ SelfUniq(_) => { ebml_w.writer.write(&[ '~' as u8 ]); }
+ SelfRegion(_, m, _) => {
// FIXME(#4846) encode custom lifetime
ebml_w.writer.write(&['&' as u8]);
encode_mutability(ebml_w, m);
source_opt: Option<DefId>) {
for source in source_opt.iter() {
ebml_w.start_tag(tag_item_method_provided_source);
- let s = def_to_str(*source);
+ let s = def_to_string(*source);
ebml_w.writer.write(s.as_bytes());
ebml_w.end_tag();
}
encode_name(ebml_w, nm);
encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
encode_def_id(ebml_w, local_def(id));
+
+ let stab = stability::lookup(ecx.tcx, field.id);
+ encode_stability(ebml_w, stab);
+
ebml_w.end_tag();
}
index
} else {
encode_symbol(ecx, ebml_w, m.def_id.node);
}
- encode_method_argument_names(ebml_w, &*ast_method.decl);
+ encode_method_argument_names(ebml_w, method_fn_decl(&*ast_method));
}
ebml_w.end_tag();
}
}
-fn encode_sized(ebml_w: &mut Encoder, sized: Sized) {
- ebml_w.start_tag(tag_items_data_item_sized);
- let ch = match sized {
- DynSize => 'd',
- StaticSize => 's',
- };
- ebml_w.wr_str(str::from_char(ch).as_slice());
- ebml_w.end_tag();
-}
-
fn encode_stability(ebml_w: &mut Encoder, stab_opt: Option<attr::Stability>) {
stab_opt.map(|stab| {
ebml_w.start_tag(tag_items_data_item_stability);
}
debug!("encoding info for item at {}",
- tcx.sess.codemap().span_to_str(item.span));
+ tcx.sess.codemap().span_to_string(item.span));
let def_id = local_def(item.id);
let stab = stability::lookup(tcx, ast_util::local_def(item.id));
// Encode all the items in this module.
for foreign_item in fm.items.iter() {
ebml_w.start_tag(tag_mod_child);
- ebml_w.wr_str(def_to_str(local_def(foreign_item.id)).as_slice());
+ ebml_w.wr_str(def_to_string(local_def(foreign_item.id)).as_slice());
ebml_w.end_tag();
}
encode_visibility(ebml_w, vis);
}
for &method_def_id in methods.iter() {
ebml_w.start_tag(tag_item_impl_method);
- let s = def_to_str(method_def_id);
+ let s = def_to_string(method_def_id);
ebml_w.writer.write(s.as_bytes());
ebml_w.end_tag();
}
ast_method)
}
}
- ItemTrait(_, sized, ref super_traits, ref ms) => {
+ ItemTrait(_, _, ref super_traits, ref ms) => {
add_to_index(item, ebml_w, index);
ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, def_id);
encode_trait_ref(ebml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
encode_name(ebml_w, item.ident.name);
encode_attributes(ebml_w, item.attrs.as_slice());
- // When we fix the rest of the supertrait nastiness (FIXME(#8559)), we
- // should no longer need this ugly little hack either.
- encode_sized(ebml_w, sized);
encode_visibility(ebml_w, vis);
encode_stability(ebml_w, stab);
for &method_def_id in ty::trait_method_def_ids(tcx, def_id).iter() {
ebml_w.end_tag();
ebml_w.start_tag(tag_mod_child);
- ebml_w.wr_str(def_to_str(method_def_id).as_slice());
+ ebml_w.wr_str(def_to_string(method_def_id).as_slice());
ebml_w.end_tag();
}
encode_path(ebml_w, path.clone());
encode_method_sort(ebml_w, 'p');
encode_inlined_item(ecx, ebml_w,
IIMethodRef(def_id, true, &*m));
- encode_method_argument_names(ebml_w, &*m.decl);
+ encode_method_argument_names(ebml_w, method_fn_decl(m));
}
}
// See above
let ecx: &EncodeContext = unsafe { mem::transmute(ecx_ptr) };
debug!("writing foreign item {}::{}",
- ecx.tcx.map.path_to_str(ni.id),
+ ecx.tcx.map.path_to_string(ni.id),
token::get_ident(ni.ident));
let mut ebml_w = unsafe {
ebml_w.end_tag();
}
-// So there's a special crate attribute called 'crate_id' which defines the
-// metadata that Rust cares about for linking crates. If the user didn't
-// provide it we will throw it in anyway with a default value.
-fn synthesize_crate_attrs(ecx: &EncodeContext,
- krate: &Crate) -> Vec<Attribute> {
-
- fn synthesize_crateid_attr(ecx: &EncodeContext) -> Attribute {
- assert!(!ecx.link_meta.crateid.name.is_empty());
-
- attr::mk_attr_inner(attr::mk_attr_id(),
- attr::mk_name_value_item_str(
- InternedString::new("crate_id"),
- token::intern_and_get_ident(ecx.link_meta
- .crateid
- .to_str()
- .as_slice())))
- }
-
- let mut attrs = Vec::new();
- for attr in krate.attrs.iter() {
- if !attr.check_name("crate_id") {
- attrs.push(*attr);
- }
- }
- attrs.push(synthesize_crateid_attr(ecx));
-
- attrs
-}
-
fn encode_crate_deps(ebml_w: &mut Encoder, cstore: &cstore::CStore) {
fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<decoder::CrateDep> {
// Pull the cnums and name,vers,hash out of cstore
cstore.iter_crate_data(|key, val| {
let dep = decoder::CrateDep {
cnum: key,
- crate_id: decoder::get_crate_id(val.data()),
- hash: decoder::get_crate_hash(val.data())
+ name: decoder::get_crate_name(val.data()),
+ hash: decoder::get_crate_hash(val.data()),
};
deps.push(dep);
});
}
}
-struct MacroDefVisitor<'a, 'b, 'c> {
- ecx: &'a EncodeContext<'b>,
- ebml_w: &'a mut Encoder<'c>
-}
-
-impl<'a, 'b, 'c> Visitor<()> for MacroDefVisitor<'a, 'b, 'c> {
- fn visit_item(&mut self, item: &Item, _: ()) {
- match item.node {
- ItemMac(..) => {
- let def = self.ecx.tcx.sess.codemap().span_to_snippet(item.span)
- .expect("Unable to find source for macro");
- self.ebml_w.start_tag(tag_macro_def);
- self.ebml_w.wr_str(def.as_slice());
- self.ebml_w.end_tag();
- }
- _ => {}
- }
- visit::walk_item(self, item, ());
- }
+/// Given a span, write the text of that span into the output stream
+/// as an exported macro
+fn encode_macro_def(ecx: &EncodeContext,
+ ebml_w: &mut Encoder,
+ span: &syntax::codemap::Span) {
+ let def = ecx.tcx.sess.codemap().span_to_snippet(*span)
+ .expect("Unable to find source for macro");
+ ebml_w.start_tag(tag_macro_def);
+ ebml_w.wr_str(def.as_slice());
+ ebml_w.end_tag();
}
-fn encode_macro_defs<'a>(ecx: &'a EncodeContext,
- krate: &Crate,
- ebml_w: &'a mut Encoder) {
+/// Serialize the text of the exported macros
+fn encode_macro_defs(ecx: &EncodeContext,
+ krate: &Crate,
+ ebml_w: &mut Encoder) {
ebml_w.start_tag(tag_exported_macros);
- {
- let mut visitor = MacroDefVisitor {
- ecx: ecx,
- ebml_w: ebml_w,
- };
- visit::walk_crate(&mut visitor, krate, ());
+ for span in krate.exported_macros.iter() {
+ encode_macro_def(ecx, ebml_w, span);
}
ebml_w.end_tag();
}
ebml_w.start_tag(tag_misc_info_crate_items);
for &item in krate.module.items.iter() {
ebml_w.start_tag(tag_mod_child);
- ebml_w.wr_str(def_to_str(local_def(item.id)).as_slice());
+ ebml_w.wr_str(def_to_string(local_def(item.id)).as_slice());
ebml_w.end_tag();
each_auxiliary_node_id(item, |auxiliary_node_id| {
ebml_w.start_tag(tag_mod_child);
- ebml_w.wr_str(def_to_str(local_def(
+ ebml_w.wr_str(def_to_string(local_def(
auxiliary_node_id)).as_slice());
ebml_w.end_tag();
true
fn encode_crate_dep(ebml_w: &mut Encoder,
dep: decoder::CrateDep) {
ebml_w.start_tag(tag_crate_dep);
- ebml_w.start_tag(tag_crate_dep_crateid);
- ebml_w.writer.write(dep.crate_id.to_str().as_bytes());
+ ebml_w.start_tag(tag_crate_dep_crate_name);
+ ebml_w.writer.write(dep.name.as_bytes());
ebml_w.end_tag();
ebml_w.start_tag(tag_crate_dep_hash);
ebml_w.writer.write(dep.hash.as_str().as_bytes());
ebml_w.end_tag();
}
-fn encode_crate_id(ebml_w: &mut Encoder, crate_id: &CrateId) {
- ebml_w.start_tag(tag_crate_crateid);
- ebml_w.writer.write(crate_id.to_str().as_bytes());
+fn encode_crate_name(ebml_w: &mut Encoder, crate_name: &str) {
+ ebml_w.start_tag(tag_crate_crate_name);
+ ebml_w.writer.write(crate_name.as_bytes());
ebml_w.end_tag();
}
let mut ebml_w = writer::Encoder::new(wr);
- encode_crate_id(&mut ebml_w, &ecx.link_meta.crateid);
+ encode_crate_name(&mut ebml_w, ecx.link_meta.crate_name.as_slice());
encode_crate_triple(&mut ebml_w,
tcx.sess
.targ_cfg
encode_dylib_dependency_formats(&mut ebml_w, &ecx);
let mut i = ebml_w.writer.tell().unwrap();
- let crate_attrs = synthesize_crate_attrs(&ecx, krate);
- encode_attributes(&mut ebml_w, crate_attrs.as_slice());
+ encode_attributes(&mut ebml_w, krate.attrs.as_slice());
stats.attr_bytes = ebml_w.writer.tell().unwrap() - i;
i = ebml_w.writer.tell().unwrap();
let mut wr = MemWriter::new();
tyencode::enc_ty(&mut wr, &tyencode::ctxt {
diag: tcx.sess.diagnostic(),
- ds: def_to_str,
+ ds: def_to_string,
tcx: tcx,
abbrevs: &RefCell::new(HashMap::new())
}, t);
// except according to those terms.
//! Finds crate binaries and loads their metadata
-
-use back::archive::{ArchiveRO, METADATA_FILENAME};
+//!
+//! Might I be the first to welcome you to a world of platform differences,
+//! version requirements, dependency graphs, conficting desires, and fun! This
+//! is the major guts (along with metadata::creader) of the compiler for loading
+//! crates and resolving dependencies. Let's take a tour!
+//!
+//! # The problem
+//!
+//! Each invocation of the compiler is immediately concerned with one primary
+//! problem, to connect a set of crates to resolved crates on the filesystem.
+//! Concretely speaking, the compiler follows roughly these steps to get here:
+//!
+//! 1. Discover a set of `extern crate` statements.
+//! 2. Transform these directives into crate names. If the directive does not
+//! have an explicit name, then the identifier is the name.
+//! 3. For each of these crate names, find a corresponding crate on the
+//! filesystem.
+//!
+//! Sounds easy, right? Let's walk into some of the nuances.
+//!
+//! ## Transitive Dependencies
+//!
+//! Let's say we've got three crates: A, B, and C. A depends on B, and B depends
+//! on C. When we're compiling A, we primarily need to find and locate B, but we
+//! also end up needing to find and locate C as well.
+//!
+//! The reason for this is that any of B's types could be composed of C's types,
+//! any function in B could return a type from C, etc. To be able to guarantee
+//! that we can always typecheck/translate any function, we have to have
+//! complete knowledge of the whole ecosystem, not just our immediate
+//! dependencies.
+//!
+//! So now as part of the "find a corresponding crate on the filesystem" step
+//! above, this involves also finding all crates for *all upstream
+//! dependencies*. This includes all dependencies transitively.
+//!
+//! ## Rlibs and Dylibs
+//!
+//! The compiler has two forms of intermediate dependencies. These are dubbed
+//! rlibs and dylibs for the static and dynamic variants, respectively. An rlib
+//! is a rustc-defined file format (currently just an ar archive) while a dylib
+//! is a platform-defined dynamic library. Each library has a metadata somewhere
+//! inside of it.
+//!
+//! When translating a crate name to a crate on the filesystem, we all of a
+//! sudden need to take into account both rlibs and dylibs! Linkage later on may
+//! use either one of these files, as each has their pros/cons. The job of crate
+//! loading is to discover what's possible by finding all candidates.
+//!
+//! Most parts of this loading systems keep the dylib/rlib as just separate
+//! variables.
+//!
+//! ## Where to look?
+//!
+//! We can't exactly scan your whole hard drive when looking for dependencies,
+//! so we need to places to look. Currently the compiler will implicitly add the
+//! target lib search path ($prefix/lib/rustlib/$target/lib) to any compilation,
+//! and otherwise all -L flags are added to the search paths.
+//!
+//! ## What criterion to select on?
+//!
+//! This a pretty tricky area of loading crates. Given a file, how do we know
+//! whether it's the right crate? Currently, the rules look along these lines:
+//!
+//! 1. Does the filename match an rlib/dylib pattern? That is to say, does the
+//! filename have the right prefix/suffix?
+//! 2. Does the filename have the right prefix for the crate name being queried?
+//! This is filtering for files like `libfoo*.rlib` and such.
+//! 3. Is the file an actual rust library? This is done by loading the metadata
+//! from the library and making sure it's actually there.
+//! 4. Does the name in the metadata agree with the name of the library?
+//! 5. Does the target in the metadata agree with the current target?
+//! 6. Does the SVH match? (more on this later)
+//!
+//! If the file answeres `yes` to all these questions, then the file is
+//! considered as being *candidate* for being accepted. It is illegal to have
+//! more than two candidates as the compiler has no method by which to resolve
+//! this conflict. Additionally, rlib/dylib candidates are considered
+//! separately.
+//!
+//! After all this has happened, we have 1 or two files as candidates. These
+//! represent the rlib/dylib file found for a library, and they're returned as
+//! being found.
+//!
+//! ### What about versions?
+//!
+//! A lot of effort has been put forth to remove versioning from the compiler.
+//! There have been forays in the past to have versioning baked in, but it was
+//! largely always deemed insufficient to the point that it was recognized that
+//! it's probably something the compiler shouldn't do anyway due to its
+//! complicated nature and the state of the half-baked solutions.
+//!
+//! With a departure from versioning, the primary criterion for loading crates
+//! is just the name of a crate. If we stopped here, it would imply that you
+//! could never link two crates of the same name from different sources
+//! together, which is clearly a bad state to be in.
+//!
+//! To resolve this problem, we come to the next section!
+//!
+//! # Expert Mode
+//!
+//! A number of flags have been added to the compiler to solve the "version
+//! problem" in the previous section, as well as generally enabling more
+//! powerful usage of the crate loading system of the compiler. The goal of
+//! these flags and options are to enable third-party tools to drive the
+//! compiler with prior knowledge about how the world should look.
+//!
+//! ## The `--extern` flag
+//!
+//! The compiler accepts a flag of this form a number of times:
+//!
+//! ```notrust
+//! --extern crate-name=path/to/the/crate.rlib
+//! ```
+//!
+//! This flag is basically the following letter to the compiler:
+//!
+//! > Dear rustc,
+//! >
+//! > When you are attempting to load the immediate dependency `crate-name`, I
+//! > would like you too assume that the library is located at
+//! > `path/to/the/crate.rlib`, and look nowhere else. Also, please do not
+//! > assume that the path I specified has the name `crate-name`.
+//!
+//! This flag basically overrides most matching logic except for validating that
+//! the file is indeed a rust library. The same `crate-name` can be specified
+//! twice to specify the rlib/dylib pair.
+//!
+//! ## Enabling "multiple versions"
+//!
+//! This basically boils down to the ability to specify arbitrary packages to
+//! the compiler. For example, if crate A wanted to use Bv1 and Bv2, then it
+//! would look something like:
+//!
+//! ```ignore
+//! extern crate b1;
+//! extern crate b2;
+//!
+//! fn main() {}
+//! ```
+//!
+//! and the compiler would be invoked as:
+//!
+//! ```notrust
+//! rustc a.rs --extern b1=path/to/libb1.rlib --extern b2=path/to/libb2.rlib
+//! ```
+//!
+//! In this scenario there are two crates named `b` and the compiler must be
+//! manually driven to be informed where each crate is.
+//!
+//! ## Frobbing symbols
+//!
+//! One of the immediate problems with linking the same library together twice
+//! in the same problem is dealing with duplicate symbols. The primary way to
+//! deal with this in rustc is to add hashes to the end of each symbol.
+//!
+//! In order to force hashes to change between versions of a library, if
+//! desired, the compiler exposes an option `-C metadata=foo`, which is used to
+//! initially seed each symbol hash. The string `foo` is prepended to each
+//! string-to-hash to ensure that symbols change over time.
+//!
+//! ## Loading transitive dependencies
+//!
+//! Dealing with same-named-but-distinct crates is not just a local problem, but
+//! one that also needs to be dealt with for transitive dependences. Note that
+//! in the letter above `--extern` flags only apply to the *local* set of
+//! dependencies, not the upstream transitive dependencies. Consider this
+//! dependency graph:
+//!
+//! ```notrust
+//! A.1 A.2
+//! | |
+//! | |
+//! B C
+//! \ /
+//! \ /
+//! D
+//! ```
+//!
+//! In this scenario, when we compile `D`, we need to be able to distinctly
+//! resolve `A.1` and `A.2`, but an `--extern` flag cannot apply to these
+//! transitive dependencies.
+//!
+//! Note that the key idea here is that `B` and `C` are both *already compiled*.
+//! That is, they have already resolved their dependencies. Due to unrelated
+//! technical reasons, when a library is compiled, it is only compatible with
+//! the *exact same* version of the upstream libraries it was compiled against.
+//! We use the "Strict Version Hash" to identify the exact copy of an upstream
+//! library.
+//!
+//! With this knowledge, we know that `B` and `C` will depend on `A` with
+//! different SVH values, so we crawl the normal `-L` paths looking for
+//! `liba*.rlib` and filter based on the contained SVH.
+//!
+//! In the end, this ends up not needing `--extern` to specify upstream
+//! transitive dependencies.
+//!
+//! # Wrapping up
+//!
+//! That's the general overview of loading crates in the compiler, but it's by
+//! no means all of the necessary details. Take a look at the rest of
+//! metadata::loader or metadata::creader for all the juicy details!
+
+use back::archive::{METADATA_FILENAME};
use back::svh::Svh;
use driver::session::Session;
-use lib::llvm::{False, llvm, ObjectFile, mk_section_iter};
+use llvm;
+use llvm::{False, ObjectFile, mk_section_iter};
+use llvm::archive_ro::ArchiveRO;
use metadata::cstore::{MetadataBlob, MetadataVec, MetadataArchive};
use metadata::decoder;
use metadata::encoder;
use syntax::abi;
use syntax::codemap::Span;
use syntax::diagnostic::SpanHandler;
-use syntax::crateid::CrateId;
-use syntax::attr::AttrMetaMethods;
use util::fs;
use std::c_str::ToCStr;
pub sess: &'a Session,
pub span: Span,
pub ident: &'a str,
- pub crate_id: &'a CrateId,
- pub id_hash: &'a str,
+ pub crate_name: &'a str,
pub hash: Option<&'a Svh>,
pub triple: &'a str,
pub os: abi::Os,
pub root: &'a Option<CratePaths>,
pub rejected_via_hash: Vec<CrateMismatch>,
pub rejected_via_triple: Vec<CrateMismatch>,
+ pub should_match_name: bool,
}
pub struct Library {
}
fn find_library_crate(&mut self) -> Option<Library> {
+ // If an SVH is specified, then this is a transitive dependency that
+ // must be loaded via -L plus some filtering.
+ if self.hash.is_none() {
+ self.should_match_name = false;
+ match self.find_commandline_library() {
+ Some(l) => return Some(l),
+ None => {}
+ }
+ self.should_match_name = true;
+ }
+
let dypair = self.dylibname();
// want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
let dylib_prefix = dypair.map(|(prefix, _)| {
- format!("{}{}-", prefix, self.crate_id.name)
+ format!("{}{}", prefix, self.crate_name)
});
- let rlib_prefix = format!("lib{}-", self.crate_id.name);
+ let rlib_prefix = format!("lib{}", self.crate_name);
let mut candidates = HashMap::new();
// First, find all possible candidate rlibs and dylibs purely based on
// the name of the files themselves. We're trying to match against an
- // exact crate_id and a possibly an exact hash.
+ // exact crate name and a possibly an exact hash.
//
// During this step, we can filter all found libraries based on the
// name and id found in the crate id (we ignore the path portion for
None => return FileDoesntMatch,
Some(file) => file,
};
- if file.starts_with(rlib_prefix.as_slice()) &&
+ let (hash, rlib) = if file.starts_with(rlib_prefix.as_slice()) &&
file.ends_with(".rlib") {
- info!("rlib candidate: {}", path.display());
- match self.try_match(file, rlib_prefix.as_slice(), ".rlib") {
- Some(hash) => {
- info!("rlib accepted, hash: {}", hash);
- let slot = candidates.find_or_insert_with(hash, |_| {
- (HashSet::new(), HashSet::new())
- });
- let (ref mut rlibs, _) = *slot;
- rlibs.insert(fs::realpath(path).unwrap());
- FileMatches
- }
- None => {
- info!("rlib rejected");
- FileDoesntMatch
- }
- }
+ (file.slice(rlib_prefix.len(), file.len() - ".rlib".len()),
+ true)
} else if dypair.map_or(false, |(_, suffix)| {
file.starts_with(dylib_prefix.get_ref().as_slice()) &&
file.ends_with(suffix)
}) {
let (_, suffix) = dypair.unwrap();
let dylib_prefix = dylib_prefix.get_ref().as_slice();
- info!("dylib candidate: {}", path.display());
- match self.try_match(file, dylib_prefix, suffix) {
- Some(hash) => {
- info!("dylib accepted, hash: {}", hash);
- let slot = candidates.find_or_insert_with(hash, |_| {
- (HashSet::new(), HashSet::new())
- });
- let (_, ref mut dylibs) = *slot;
- dylibs.insert(fs::realpath(path).unwrap());
- FileMatches
- }
- None => {
- info!("dylib rejected");
- FileDoesntMatch
- }
- }
+ (file.slice(dylib_prefix.len(), file.len() - suffix.len()),
+ false)
} else {
- FileDoesntMatch
+ return FileDoesntMatch
+ };
+ info!("lib candidate: {}", path.display());
+ let slot = candidates.find_or_insert_with(hash.to_string(), |_| {
+ (HashSet::new(), HashSet::new())
+ });
+ let (ref mut rlibs, ref mut dylibs) = *slot;
+ if rlib {
+ rlibs.insert(fs::realpath(path).unwrap());
+ } else {
+ dylibs.insert(fs::realpath(path).unwrap());
}
+ FileMatches
});
// We have now collected all known libraries into a set of candidates
_ => {
self.sess.span_err(self.span,
format!("multiple matching crates for `{}`",
- self.crate_id.name).as_slice());
+ self.crate_name).as_slice());
self.sess.note("candidates:");
for lib in libraries.iter() {
match lib.dylib {
None => {}
}
let data = lib.metadata.as_slice();
- let crate_id = decoder::get_crate_id(data);
- note_crateid_attr(self.sess.diagnostic(), &crate_id);
+ let name = decoder::get_crate_name(data);
+ note_crate_name(self.sess.diagnostic(), name.as_slice());
}
None
}
}
}
- // Attempts to match the requested version of a library against the file
- // specified. The prefix/suffix are specified (disambiguates between
- // rlib/dylib).
- //
- // The return value is `None` if `file` doesn't look like a rust-generated
- // library, or if a specific version was requested and it doesn't match the
- // apparent file's version.
- //
- // If everything checks out, then `Some(hash)` is returned where `hash` is
- // the listed hash in the filename itself.
- fn try_match(&self, file: &str, prefix: &str, suffix: &str) -> Option<String>{
- let middle = file.slice(prefix.len(), file.len() - suffix.len());
- debug!("matching -- {}, middle: {}", file, middle);
- let mut parts = middle.splitn('-', 1);
- let hash = match parts.next() { Some(h) => h, None => return None };
- debug!("matching -- {}, hash: {} (want {})", file, hash, self.id_hash);
- let vers = match parts.next() { Some(v) => v, None => return None };
- debug!("matching -- {}, vers: {} (want {})", file, vers,
- self.crate_id.version);
- match self.crate_id.version {
- Some(ref version) if version.as_slice() != vers => return None,
- Some(..) => {} // check the hash
-
- // hash is irrelevant, no version specified
- None => return Some(hash.to_string())
- }
- debug!("matching -- {}, vers ok", file);
- // hashes in filenames are prefixes of the "true hash"
- if self.id_hash == hash.as_slice() {
- debug!("matching -- {}, hash ok", file);
- Some(hash.to_string())
- } else {
- None
- }
- }
-
// Attempts to extract *one* library from the set `m`. If the set has no
// elements, `None` is returned. If the set has more than one element, then
// the errors and notes are emitted about the set of libraries.
format!("multiple {} candidates for `{}` \
found",
flavor,
- self.crate_id.name).as_slice());
+ self.crate_name).as_slice());
self.sess.span_note(self.span,
format!(r"candidate #1: {}",
ret.get_ref()
}
fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> bool {
- match decoder::maybe_get_crate_id(crate_data) {
- Some(ref id) if self.crate_id.matches(id) => {}
- _ => { info!("Rejecting via crate_id"); return false }
+ if self.should_match_name {
+ match decoder::maybe_get_crate_name(crate_data) {
+ Some(ref name) if self.crate_name == name.as_slice() => {}
+ _ => { info!("Rejecting via crate name"); return false }
+ }
}
let hash = match decoder::maybe_get_crate_hash(crate_data) {
Some(hash) => hash, None => {
}
};
- let triple = decoder::get_crate_triple(crate_data);
+ let triple = match decoder::get_crate_triple(crate_data) {
+ None => { debug!("triple not present"); return false }
+ Some(t) => t,
+ };
if triple.as_slice() != self.triple {
info!("Rejecting via crate triple: expected {} got {}", self.triple, triple);
self.rejected_via_triple.push(CrateMismatch {
}
}
+ fn find_commandline_library(&mut self) -> Option<Library> {
+ let locs = match self.sess.opts.externs.find_equiv(&self.crate_name) {
+ Some(s) => s,
+ None => return None,
+ };
+
+ // First, filter out all libraries that look suspicious. We only accept
+ // files which actually exist that have the correct naming scheme for
+ // rlibs/dylibs.
+ let sess = self.sess;
+ let dylibname = self.dylibname();
+ let mut locs = locs.iter().map(|l| Path::new(l.as_slice())).filter(|loc| {
+ if !loc.exists() {
+ sess.err(format!("extern location does not exist: {}",
+ loc.display()).as_slice());
+ return false;
+ }
+ let file = loc.filename_str().unwrap();
+ if file.starts_with("lib") && file.ends_with(".rlib") {
+ return true
+ } else {
+ match dylibname {
+ Some((prefix, suffix)) => {
+ if file.starts_with(prefix) && file.ends_with(suffix) {
+ return true
+ }
+ }
+ None => {}
+ }
+ }
+ sess.err(format!("extern location is of an unknown type: {}",
+ loc.display()).as_slice());
+ false
+ });
+
+ // Now that we have an itertor of good candidates, make sure there's at
+ // most one rlib and at most one dylib.
+ let mut rlibs = HashSet::new();
+ let mut dylibs = HashSet::new();
+ for loc in locs {
+ if loc.filename_str().unwrap().ends_with(".rlib") {
+ rlibs.insert(loc.clone());
+ } else {
+ dylibs.insert(loc.clone());
+ }
+ }
+
+ // Extract the rlib/dylib pair.
+ let mut metadata = None;
+ let rlib = self.extract_one(rlibs, "rlib", &mut metadata);
+ let dylib = self.extract_one(dylibs, "dylib", &mut metadata);
+
+ if rlib.is_none() && dylib.is_none() { return None }
+ match metadata {
+ Some(metadata) => Some(Library {
+ dylib: dylib,
+ rlib: rlib,
+ metadata: metadata,
+ }),
+ None => None,
+ }
+ }
}
-pub fn note_crateid_attr(diag: &SpanHandler, crateid: &CrateId) {
- diag.handler().note(format!("crate_id: {}", crateid.to_str()).as_slice());
+pub fn note_crate_name(diag: &SpanHandler, name: &str) {
+ diag.handler().note(format!("crate name: {}", name).as_slice());
}
impl ArchiveMetadata {
op: |&mut MemWriter, &ctxt, &T|) {
for &space in subst::ParamSpace::all().iter() {
mywrite!(w, "[");
- for t in v.get_vec(space).iter() {
+ for t in v.get_slice(space).iter() {
op(w, cx, t);
}
mywrite!(w, "]");
use middle::subst::VecPerParamSpace;
use middle::typeck::{MethodCall, MethodCallee, MethodOrigin};
use middle::{ty, typeck};
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
use syntax::{ast, ast_map, ast_util, codemap, fold};
use syntax::codemap::Span;
e::IIMethodRef(_, _, m) => m.id,
};
debug!("> Encoding inlined item: {} ({})",
- ecx.tcx.map.path_to_str(id),
+ ecx.tcx.map.path_to_string(id),
ebml_w.writer.tell());
let ii = simplify_ast(ii);
ebml_w.end_tag();
debug!("< Encoded inlined fn: {} ({})",
- ecx.tcx.map.path_to_str(id),
+ ecx.tcx.map.path_to_string(id),
ebml_w.writer.tell());
}
debug!("> Decoding inlined fn: {}::?",
{
// Do an Option dance to use the path after it is moved below.
- let s = ast_map::path_to_str(ast_map::Values(path.iter()));
+ let s = ast_map::path_to_string(ast_map::Values(path.iter()));
path_as_str = Some(s);
path_as_str.as_ref().map(|x| x.as_slice())
});
let ident = match ii {
ast::IIItem(i) => i.ident,
ast::IIForeign(i) => i.ident,
- ast::IIMethod(_, _, m) => m.ident,
+ ast::IIMethod(_, _, m) => ast_util::method_ident(&*m),
};
debug!("Fn named: {}", token::get_ident(ident));
debug!("< Decoded inlined fn: {}::{}",
match ii {
ast::IIItem(i) => {
debug!(">>> DECODED ITEM >>>\n{}\n<<< DECODED ITEM <<<",
- syntax::print::pprust::item_to_str(&*i));
+ syntax::print::pprust::item_to_string(&*i));
}
_ => { }
}
// HACK we're not dropping items.
e::IIItemRef(i) => ast::IIItem(fold::noop_fold_item(i, &mut fld)
.expect_one("expected one item")),
- e::IIMethodRef(d, p, m) => ast::IIMethod(d, p, fold::noop_fold_method(m, &mut fld)),
+ e::IIMethodRef(d, p, m) => ast::IIMethod(d, p, fold::noop_fold_method(m, &mut fld)
+ .expect_one(
+ "noop_fold_method must produce exactly one method")),
e::IIForeignRef(i) => ast::IIForeign(fold::noop_fold_foreign_item(i, &mut fld))
}
}
ast::IIItem(fld.fold_item(i).expect_one("expected one item"))
}
ast::IIMethod(d, is_provided, m) => {
- ast::IIMethod(xcx.tr_def_id(d), is_provided, fld.fold_method(m))
+ ast::IIMethod(xcx.tr_def_id(d), is_provided, fld.fold_method(m)
+ .expect_one("expected one method"))
}
ast::IIForeign(i) => ast::IIForeign(fld.fold_foreign_item(i))
}
v: &subst::VecPerParamSpace<T>,
f: |&mut Encoder, &T|) {
for &space in subst::ParamSpace::all().iter() {
- ebml_w.emit_from_vec(v.get_vec(space).as_slice(),
+ ebml_w.emit_from_vec(v.get_slice(space),
|ebml_w, n| Ok(f(ebml_w, n))).unwrap();
}
}
fn ty_str_ctxt<'a>(&'a self) -> tyencode::ctxt<'a> {
tyencode::ctxt {
diag: self.tcx.sess.diagnostic(),
- ds: e::def_to_str,
+ ds: e::def_to_string,
tcx: self.tcx,
abbrevs: &self.type_abbrevs
}
c::tag_table_node_type => {
let ty = val_dsr.read_ty(xcx);
debug!("inserting ty for node {:?}: {}",
- id, ty_to_str(dcx.tcx, ty));
+ id, ty_to_string(dcx.tcx, ty));
dcx.tcx.node_types.borrow_mut().insert(id as uint, ty);
}
c::tag_table_item_subst => {
fn foo() {}
));
}
-
+/* NOTE: When there's a snapshot, update this (yay quasiquoter!)
#[test]
fn test_smalltalk() {
let cx = mk_ctxt();
fn foo() -> int { 3 + 4 } // first smalltalk program ever executed.
));
}
+*/
#[test]
fn test_more() {
).unwrap());
match (item_out, item_exp) {
(ast::IIItem(item_out), ast::IIItem(item_exp)) => {
- assert!(pprust::item_to_str(item_out) == pprust::item_to_str(item_exp));
+ assert!(pprust::item_to_string(item_out) == pprust::item_to_string(item_exp));
}
_ => fail!()
}
"it".to_string()
} else {
format!("`{}`",
- self.bccx.loan_path_to_str(&*old_loan.loan_path))
+ self.bccx.loan_path_to_string(&*old_loan.loan_path))
};
match (new_loan.kind, old_loan.kind) {
new_loan.span,
format!("cannot borrow `{}` as mutable \
more than once at a time",
- self.bccx.loan_path_to_str(
+ self.bccx.loan_path_to_string(
&*new_loan.loan_path)).as_slice());
}
new_loan.span,
format!("closure requires unique access to `{}` \
but {} is already borrowed",
- self.bccx.loan_path_to_str(&*new_loan.loan_path),
+ self.bccx.loan_path_to_string(&*new_loan.loan_path),
old_pronoun).as_slice());
}
new_loan.span,
format!("cannot borrow `{}` as {} because \
previous closure requires unique access",
- self.bccx.loan_path_to_str(&*new_loan.loan_path),
+ self.bccx.loan_path_to_string(&*new_loan.loan_path),
new_loan.kind.to_user_str()).as_slice());
}
new_loan.span,
format!("cannot borrow `{}` as {} because \
{} is also borrowed as {}",
- self.bccx.loan_path_to_str(&*new_loan.loan_path),
+ self.bccx.loan_path_to_string(&*new_loan.loan_path),
new_loan.kind.to_user_str(),
old_pronoun,
old_loan.kind.to_user_str()).as_slice());
self.bccx.span_note(
span,
format!("borrow occurs due to use of `{}` in closure",
- self.bccx.loan_path_to_str(
+ self.bccx.loan_path_to_string(
&*new_loan.loan_path)).as_slice());
}
_ => { }
format!("the mutable borrow prevents subsequent \
moves, borrows, or modification of `{0}` \
until the borrow ends",
- self.bccx.loan_path_to_str(
+ self.bccx.loan_path_to_string(
&*old_loan.loan_path))
}
format!("the immutable borrow prevents subsequent \
moves or mutable borrows of `{0}` \
until the borrow ends",
- self.bccx.loan_path_to_str(&*old_loan.loan_path))
+ self.bccx.loan_path_to_string(&*old_loan.loan_path))
}
ty::UniqueImmBorrow => {
format!("the unique capture prevents subsequent \
moves or borrows of `{0}` \
until the borrow ends",
- self.bccx.loan_path_to_str(&*old_loan.loan_path))
+ self.bccx.loan_path_to_string(&*old_loan.loan_path))
}
};
euv::ClosureCapture(_) => {
format!("previous borrow of `{}` occurs here due to \
use in closure",
- self.bccx.loan_path_to_str(&*old_loan.loan_path))
+ self.bccx.loan_path_to_string(&*old_loan.loan_path))
}
euv::OverloadedOperator(..) |
euv::ClosureInvocation(..) |
euv::RefBinding(..) => {
format!("previous borrow of `{}` occurs here",
- self.bccx.loan_path_to_str(&*old_loan.loan_path))
+ self.bccx.loan_path_to_string(&*old_loan.loan_path))
}
};
self.bccx.span_err(
span,
format!("cannot use `{}` because it was mutably borrowed",
- self.bccx.loan_path_to_str(copy_path).as_slice())
+ self.bccx.loan_path_to_string(copy_path).as_slice())
.as_slice());
self.bccx.span_note(
loan_span,
format!("borrow of `{}` occurs here",
- self.bccx.loan_path_to_str(&*loan_path).as_slice())
+ self.bccx.loan_path_to_string(&*loan_path).as_slice())
.as_slice());
}
}
let err_message = match move_kind {
move_data::Captured =>
format!("cannot move `{}` into closure because it is borrowed",
- self.bccx.loan_path_to_str(move_path).as_slice()),
+ self.bccx.loan_path_to_string(move_path).as_slice()),
move_data::Declared |
move_data::MoveExpr |
move_data::MovePat =>
format!("cannot move out of `{}` because it is borrowed",
- self.bccx.loan_path_to_str(move_path).as_slice())
+ self.bccx.loan_path_to_string(move_path).as_slice())
};
self.bccx.span_err(span, err_message.as_slice());
self.bccx.span_note(
loan_span,
format!("borrow of `{}` occurs here",
- self.bccx.loan_path_to_str(&*loan_path).as_slice())
+ self.bccx.loan_path_to_string(&*loan_path).as_slice())
.as_slice());
}
}
borrow_kind: ty::BorrowKind)
-> UseError {
debug!("analyze_restrictions_on_use(expr_id={:?}, use_path={})",
- self.tcx().map.node_to_str(expr_id),
+ self.tcx().map.node_to_string(expr_id),
use_path.repr(self.tcx()));
let mut ret = UseOk;
assignment_span,
format!("cannot assign to {} {} `{}`",
assignee_cmt.mutbl.to_user_str(),
- self.bccx.cmt_to_str(&*assignee_cmt),
- self.bccx.loan_path_to_str(&*lp)).as_slice());
+ self.bccx.cmt_to_string(&*assignee_cmt),
+ self.bccx.loan_path_to_string(&*lp)).as_slice());
}
None => {
self.bccx.span_err(
assignment_span,
format!("cannot assign to {} {}",
assignee_cmt.mutbl.to_user_str(),
- self.bccx.cmt_to_str(&*assignee_cmt)).as_slice());
+ self.bccx.cmt_to_string(&*assignee_cmt)).as_slice());
}
}
return;
self.bccx.span_err(
span,
format!("cannot assign to `{}` because it is borrowed",
- self.bccx.loan_path_to_str(loan_path)).as_slice());
+ self.bccx.loan_path_to_string(loan_path)).as_slice());
self.bccx.span_note(
loan.span,
format!("borrow of `{}` occurs here",
- self.bccx.loan_path_to_str(loan_path)).as_slice());
+ self.bccx.loan_path_to_string(loan_path)).as_slice());
}
}
bccx.span_err(
move_from.span,
format!("cannot move out of {}",
- bccx.cmt_to_str(&*move_from)).as_slice());
+ bccx.cmt_to_string(&*move_from)).as_slice());
}
mc::cat_downcast(ref b) |
move_to_span: codemap::Span,
pat_ident: &ast::Ident,
is_first_note: bool) {
- let pat_name = pprust::ident_to_str(pat_ident);
+ let pat_name = pprust::ident_to_string(pat_ident);
if is_first_note {
bccx.span_note(
move_to_span,
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! This module provides linkage between rustc::middle::graph and
+//! libgraphviz traits, specialized to attaching borrowck analysis
+//! data to rendered labels.
+
+/// For clarity, rename the graphviz crate locally to dot.
+use dot = graphviz;
+pub use middle::cfg::graphviz::{Node, Edge};
+use cfg_dot = middle::cfg::graphviz;
+
+use middle::borrowck;
+use middle::borrowck::{BorrowckCtxt, LoanPath};
+use middle::cfg::{CFGIndex};
+use middle::dataflow::{DataFlowOperator, DataFlowContext, EntryOrExit};
+use middle::dataflow;
+
+use std::rc::Rc;
+use std::str;
+
+#[deriving(Show)]
+pub enum Variant {
+ Loans,
+ Moves,
+ Assigns,
+}
+
+impl Variant {
+ pub fn short_name(&self) -> &'static str {
+ match *self {
+ Loans => "loans",
+ Moves => "moves",
+ Assigns => "assigns",
+ }
+ }
+}
+
+pub struct DataflowLabeller<'a> {
+ pub inner: cfg_dot::LabelledCFG<'a>,
+ pub variants: Vec<Variant>,
+ pub borrowck_ctxt: &'a BorrowckCtxt<'a>,
+ pub analysis_data: &'a borrowck::AnalysisData<'a>,
+}
+
+impl<'a> DataflowLabeller<'a> {
+ fn dataflow_for(&self, e: EntryOrExit, n: &Node<'a>) -> String {
+ let id = n.val1().data.id;
+ debug!("dataflow_for({}, id={}) {}", e, id, self.variants);
+ let mut sets = "".to_string();
+ let mut seen_one = false;
+ for &variant in self.variants.iter() {
+ if seen_one { sets.push_str(" "); } else { seen_one = true; }
+ sets.push_str(variant.short_name());
+ sets.push_str(": ");
+ sets.push_str(self.dataflow_for_variant(e, n, variant).as_slice());
+ }
+ sets
+ }
+
+ fn dataflow_for_variant(&self, e: EntryOrExit, n: &Node, v: Variant) -> String {
+ let cfgidx = n.val0();
+ match v {
+ Loans => self.dataflow_loans_for(e, cfgidx),
+ Moves => self.dataflow_moves_for(e, cfgidx),
+ Assigns => self.dataflow_assigns_for(e, cfgidx),
+ }
+ }
+
+ fn build_set<O:DataFlowOperator>(&self,
+ e: EntryOrExit,
+ cfgidx: CFGIndex,
+ dfcx: &DataFlowContext<'a, O>,
+ to_lp: |uint| -> Rc<LoanPath>) -> String {
+ let mut saw_some = false;
+ let mut set = "{".to_string();
+ dfcx.each_bit_for_node(e, cfgidx, |index| {
+ let lp = to_lp(index);
+ if saw_some {
+ set.push_str(", ");
+ }
+ let loan_str = self.borrowck_ctxt.loan_path_to_string(&*lp);
+ set.push_str(loan_str.as_slice());
+ saw_some = true;
+ true
+ });
+ set.append("}")
+ }
+
+ fn dataflow_loans_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
+ let dfcx = &self.analysis_data.loans;
+ let loan_index_to_path = |loan_index| {
+ let all_loans = &self.analysis_data.all_loans;
+ all_loans.get(loan_index).loan_path()
+ };
+ self.build_set(e, cfgidx, dfcx, loan_index_to_path)
+ }
+
+ fn dataflow_moves_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
+ let dfcx = &self.analysis_data.move_data.dfcx_moves;
+ let move_index_to_path = |move_index| {
+ let move_data = &self.analysis_data.move_data.move_data;
+ let moves = move_data.moves.borrow();
+ let move = moves.get(move_index);
+ move_data.path_loan_path(move.path)
+ };
+ self.build_set(e, cfgidx, dfcx, move_index_to_path)
+ }
+
+ fn dataflow_assigns_for(&self, e: EntryOrExit, cfgidx: CFGIndex) -> String {
+ let dfcx = &self.analysis_data.move_data.dfcx_assign;
+ let assign_index_to_path = |assign_index| {
+ let move_data = &self.analysis_data.move_data.move_data;
+ let assignments = move_data.var_assignments.borrow();
+ let assignment = assignments.get(assign_index);
+ move_data.path_loan_path(assignment.path)
+ };
+ self.build_set(e, cfgidx, dfcx, assign_index_to_path)
+ }
+}
+
+impl<'a> dot::Labeller<'a, Node<'a>, Edge<'a>> for DataflowLabeller<'a> {
+ fn graph_id(&'a self) -> dot::Id<'a> { self.inner.graph_id() }
+ fn node_id(&'a self, n: &Node<'a>) -> dot::Id<'a> { self.inner.node_id(n) }
+ fn node_label(&'a self, n: &Node<'a>) -> dot::LabelText<'a> {
+ let prefix = self.dataflow_for(dataflow::Entry, n);
+ let suffix = self.dataflow_for(dataflow::Exit, n);
+ let inner_label = self.inner.node_label(n);
+ inner_label
+ .prefix_line(dot::LabelStr(str::Owned(prefix)))
+ .suffix_line(dot::LabelStr(str::Owned(suffix)))
+ }
+ fn edge_label(&'a self, e: &Edge<'a>) -> dot::LabelText<'a> { self.inner.edge_label(e) }
+}
+
+impl<'a> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for DataflowLabeller<'a> {
+ fn nodes(&self) -> dot::Nodes<'a, Node<'a>> { self.inner.nodes() }
+ fn edges(&self) -> dot::Edges<'a, Edge<'a>> { self.inner.edges() }
+ fn source(&self, edge: &Edge<'a>) -> Node<'a> { self.inner.source(edge) }
+ fn target(&self, edge: &Edge<'a>) -> Node<'a> { self.inner.target(edge) }
+}
use std::string::String;
use syntax::ast;
use syntax::ast_map;
+use syntax::ast_map::blocks::{FnLikeNode, FnParts};
use syntax::ast_util;
use syntax::codemap::Span;
use syntax::parse::token;
pub mod gather_loans;
+pub mod graphviz;
+
pub mod move_data;
#[deriving(Clone)]
}
}
+/// Collection of conclusions determined via borrow checker analyses.
+pub struct AnalysisData<'a> {
+ pub all_loans: Vec<Loan>,
+ pub loans: DataFlowContext<'a, LoanDataFlowOperator>,
+ pub move_data: move_data::FlowedMoveData<'a>,
+}
+
fn borrowck_fn(this: &mut BorrowckCtxt,
fk: &FnKind,
decl: &ast::FnDecl,
sp: Span,
id: ast::NodeId) {
debug!("borrowck_fn(id={})", id);
+ let cfg = cfg::CFG::new(this.tcx, body);
+ let AnalysisData { all_loans,
+ loans: loan_dfcx,
+ move_data:flowed_moves } =
+ build_borrowck_dataflow_data(this, fk, decl, &cfg, body, sp, id);
+
+ check_loans::check_loans(this, &loan_dfcx, flowed_moves,
+ all_loans.as_slice(), decl, body);
+
+ visit::walk_fn(this, fk, decl, body, sp, ());
+}
+fn build_borrowck_dataflow_data<'a>(this: &mut BorrowckCtxt<'a>,
+ fk: &FnKind,
+ decl: &ast::FnDecl,
+ cfg: &cfg::CFG,
+ body: &ast::Block,
+ sp: Span,
+ id: ast::NodeId) -> AnalysisData<'a> {
// Check the body of fn items.
let id_range = ast_util::compute_id_range_for_fn_body(fk, decl, body, sp, id);
let (all_loans, move_data) =
gather_loans::gather_loans_in_fn(this, decl, body);
- let cfg = cfg::CFG::new(this.tcx, body);
let mut loan_dfcx =
DataFlowContext::new(this.tcx,
"borrowck",
Some(decl),
- &cfg,
+ cfg,
LoanDataFlowOperator,
id_range,
all_loans.len());
loan_dfcx.add_gen(loan.gen_scope, loan_idx);
loan_dfcx.add_kill(loan.kill_scope, loan_idx);
}
- loan_dfcx.add_kills_from_flow_exits(&cfg);
- loan_dfcx.propagate(&cfg, body);
+ loan_dfcx.add_kills_from_flow_exits(cfg);
+ loan_dfcx.propagate(cfg, body);
let flowed_moves = move_data::FlowedMoveData::new(move_data,
this.tcx,
- &cfg,
+ cfg,
id_range,
decl,
body);
- check_loans::check_loans(this, &loan_dfcx, flowed_moves,
- all_loans.as_slice(), decl, body);
+ AnalysisData { all_loans: all_loans,
+ loans: loan_dfcx,
+ move_data:flowed_moves }
+}
- visit::walk_fn(this, fk, decl, body, sp, ());
+/// This and a `ty::ctxt` is all you need to run the dataflow analyses
+/// used in the borrow checker.
+pub struct FnPartsWithCFG<'a> {
+ pub fn_parts: FnParts<'a>,
+ pub cfg: &'a cfg::CFG,
+}
+
+impl<'a> FnPartsWithCFG<'a> {
+ pub fn from_fn_like(f: &'a FnLikeNode,
+ g: &'a cfg::CFG) -> FnPartsWithCFG<'a> {
+ FnPartsWithCFG { fn_parts: f.to_fn_parts(), cfg: g }
+ }
+}
+
+/// Accessor for introspective clients inspecting `AnalysisData` and
+/// the `BorrowckCtxt` itself , e.g. the flowgraph visualizer.
+pub fn build_borrowck_dataflow_data_for_fn<'a>(
+ tcx: &'a ty::ctxt,
+ input: FnPartsWithCFG<'a>) -> (BorrowckCtxt<'a>, AnalysisData<'a>) {
+
+ let mut bccx = BorrowckCtxt {
+ tcx: tcx,
+ stats: box(GC) BorrowStats {
+ loaned_paths_same: Cell::new(0),
+ loaned_paths_imm: Cell::new(0),
+ stable_paths: Cell::new(0),
+ guaranteed_paths: Cell::new(0),
+ }
+ };
+
+ let p = input.fn_parts;
+
+ let dataflow_data = build_borrowck_dataflow_data(
+ &mut bccx, &p.kind, p.decl, input.cfg, p.body, p.span, p.id);
+
+ (bccx, dataflow_data)
}
// ----------------------------------------------------------------------
cause: euv::LoanCause,
}
+impl Loan {
+ pub fn loan_path(&self) -> Rc<LoanPath> {
+ self.loan_path.clone()
+ }
+}
+
#[deriving(PartialEq, Eq, Hash)]
pub enum LoanPath {
LpVar(ast::NodeId), // `x` in doc.rs
pub fn report(&self, err: BckError) {
self.span_err(
err.span,
- self.bckerr_to_str(&err).as_slice());
+ self.bckerr_to_string(&err).as_slice());
self.note_and_explain_bckerr(err);
}
use_span,
format!("{} of possibly uninitialized variable: `{}`",
verb,
- self.loan_path_to_str(lp)).as_slice());
+ self.loan_path_to_string(lp)).as_slice());
}
_ => {
let partially = if lp == moved_lp {""} else {"partially "};
format!("{} of {}moved value: `{}`",
verb,
partially,
- self.loan_path_to_str(lp)).as_slice());
+ self.loan_path_to_string(lp)).as_slice());
}
}
self.tcx.sess.span_note(
expr_span,
format!("`{}` moved here because it has type `{}`, which is {}",
- self.loan_path_to_str(moved_lp),
+ self.loan_path_to_string(moved_lp),
expr_ty.user_string(self.tcx),
suggestion).as_slice());
}
format!("`{}` moved here because it has type `{}`, \
which is moved by default (use `ref` to \
override)",
- self.loan_path_to_str(moved_lp),
+ self.loan_path_to_string(moved_lp),
pat_ty.user_string(self.tcx)).as_slice());
}
expr_span,
format!("`{}` moved into closure environment here because it \
has type `{}`, which is {}",
- self.loan_path_to_str(moved_lp),
+ self.loan_path_to_string(moved_lp),
expr_ty.user_string(self.tcx),
suggestion).as_slice());
}
self.tcx.sess.span_err(
span,
format!("re-assignment of immutable variable `{}`",
- self.loan_path_to_str(lp)).as_slice());
+ self.loan_path_to_string(lp)).as_slice());
self.tcx.sess.span_note(assign.span, "prior assignment occurs here");
}
self.tcx.sess.span_end_note(s, m);
}
- pub fn bckerr_to_str(&self, err: &BckError) -> String {
+ pub fn bckerr_to_string(&self, err: &BckError) -> String {
match err.code {
err_mutbl => {
let descr = match opt_loan_path(&err.cmt) {
None => {
format!("{} {}",
err.cmt.mutbl.to_user_str(),
- self.cmt_to_str(&*err.cmt))
+ self.cmt_to_string(&*err.cmt))
}
Some(lp) => {
format!("{} {} `{}`",
err.cmt.mutbl.to_user_str(),
- self.cmt_to_str(&*err.cmt),
- self.loan_path_to_str(&*lp))
+ self.cmt_to_string(&*err.cmt),
+ self.loan_path_to_string(&*lp))
}
};
let msg = match opt_loan_path(&err.cmt) {
None => "borrowed value".to_string(),
Some(lp) => {
- format!("`{}`", self.loan_path_to_str(&*lp))
+ format!("`{}`", self.loan_path_to_string(&*lp))
}
};
format!("{} does not live long enough", msg)
err_borrowed_pointer_too_short(..) => {
let descr = match opt_loan_path(&err.cmt) {
Some(lp) => {
- format!("`{}`", self.loan_path_to_str(&*lp))
+ format!("`{}`", self.loan_path_to_string(&*lp))
}
- None => self.cmt_to_str(&*err.cmt),
+ None => self.cmt_to_string(&*err.cmt),
};
format!("lifetime of {} is too short to guarantee \
err_borrowed_pointer_too_short(loan_scope, ptr_scope) => {
let descr = match opt_loan_path(&err.cmt) {
Some(lp) => {
- format!("`{}`", self.loan_path_to_str(&*lp))
+ format!("`{}`", self.loan_path_to_string(&*lp))
}
- None => self.cmt_to_str(&*err.cmt),
+ None => self.cmt_to_string(&*err.cmt),
};
note_and_explain_region(
self.tcx,
}
}
- pub fn append_loan_path_to_str(&self,
+ pub fn append_loan_path_to_string(&self,
loan_path: &LoanPath,
out: &mut String) {
match *loan_path {
}
LpExtend(ref lp_base, _, LpInterior(mc::InteriorField(fname))) => {
- self.append_autoderefd_loan_path_to_str(&**lp_base, out);
+ self.append_autoderefd_loan_path_to_string(&**lp_base, out);
match fname {
mc::NamedField(fname) => {
out.push_char('.');
}
mc::PositionalField(idx) => {
out.push_char('#'); // invent a notation here
- out.push_str(idx.to_str().as_slice());
+ out.push_str(idx.to_string().as_slice());
}
}
}
LpExtend(ref lp_base, _, LpInterior(mc::InteriorElement(_))) => {
- self.append_autoderefd_loan_path_to_str(&**lp_base, out);
+ self.append_autoderefd_loan_path_to_string(&**lp_base, out);
out.push_str("[..]");
}
LpExtend(ref lp_base, _, LpDeref(_)) => {
out.push_char('*');
- self.append_loan_path_to_str(&**lp_base, out);
+ self.append_loan_path_to_string(&**lp_base, out);
}
}
}
- pub fn append_autoderefd_loan_path_to_str(&self,
+ pub fn append_autoderefd_loan_path_to_string(&self,
loan_path: &LoanPath,
out: &mut String) {
match *loan_path {
// For a path like `(*x).f` or `(*x)[3]`, autoderef
// rules would normally allow users to omit the `*x`.
// So just serialize such paths to `x.f` or x[3]` respectively.
- self.append_autoderefd_loan_path_to_str(&**lp_base, out)
+ self.append_autoderefd_loan_path_to_string(&**lp_base, out)
}
LpVar(..) | LpUpvar(..) | LpExtend(_, _, LpInterior(..)) => {
- self.append_loan_path_to_str(loan_path, out)
+ self.append_loan_path_to_string(loan_path, out)
}
}
}
- pub fn loan_path_to_str(&self, loan_path: &LoanPath) -> String {
+ pub fn loan_path_to_string(&self, loan_path: &LoanPath) -> String {
let mut result = String::new();
- self.append_loan_path_to_str(loan_path, &mut result);
+ self.append_loan_path_to_string(loan_path, &mut result);
result
}
- pub fn cmt_to_str(&self, cmt: &mc::cmt_) -> String {
- self.mc().cmt_to_str(cmt)
+ pub fn cmt_to_string(&self, cmt: &mc::cmt_) -> String {
+ self.mc().cmt_to_string(cmt)
}
}
fn repr(&self, tcx: &ty::ctxt) -> String {
match self {
&LpVar(id) => {
- format!("$({})", tcx.map.node_to_str(id))
+ format!("$({})", tcx.map.node_to_string(id))
}
&LpUpvar(ty::UpvarId{ var_id, closure_expr_id }) => {
- let s = tcx.map.node_to_str(var_id);
+ let s = tcx.map.node_to_string(var_id);
format!("$({} captured by id={})", s, closure_expr_id)
}
}
}
- fn path_loan_path(&self, index: MovePathIndex) -> Rc<LoanPath> {
+ pub fn path_loan_path(&self, index: MovePathIndex) -> Rc<LoanPath> {
self.paths.borrow().get(index.get()).loan_path.clone()
}
impl<'a> FlowedMoveData<'a> {
pub fn new(move_data: MoveData,
tcx: &'a ty::ctxt,
- cfg: &'a cfg::CFG,
+ cfg: &cfg::CFG,
id_range: ast_util::IdRange,
decl: &ast::FnDecl,
body: &ast::Block)
} else if n.data.id == ast::DUMMY_NODE_ID {
dot::LabelStr("(dummy_node)".into_maybe_owned())
} else {
- let s = self.ast_map.node_to_str(n.data.id);
+ let s = self.ast_map.node_to_string(n.data.id);
// left-aligns the lines
let s = replace_newline_with_backslash_l(s);
dot::EscStr(s.into_maybe_owned())
} else {
put_one = true;
}
- let s = self.ast_map.node_to_str(node_id);
+ let s = self.ast_map.node_to_string(node_id);
// left-aligns the lines
let s = replace_newline_with_backslash_l(s);
label = label.append(format!("exiting scope_{} {}",
fn source(&self, edge: &Edge<'a>) -> Node<'a> { self.cfg.source(edge) }
fn target(&self, edge: &Edge<'a>) -> Node<'a> { self.cfg.target(edge) }
}
+
.span_err(e.span,
format!("can not cast to `{}` in a constant \
expression",
- ppaux::ty_to_str(v.tcx, ety)).as_slice())
+ ppaux::ty_to_string(v.tcx, ety)).as_slice())
}
}
ExprPath(ref pth) => {
use syntax::ast_util::{is_unguarded, walk_pat};
use syntax::codemap::{Span, Spanned, DUMMY_SP};
use syntax::owned_slice::OwnedSlice;
-use syntax::print::pprust::pat_to_str;
+use syntax::print::pprust::pat_to_string;
use syntax::visit;
use syntax::visit::{Visitor, FnKind};
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
struct Matrix(Vec<Vec<Gc<Pat>>>);
let &Matrix(ref m) = self;
let pretty_printed_matrix: Vec<Vec<String>> = m.iter().map(|row| {
- row.iter().map(|&pat| pat_to_str(pat)).collect::<Vec<String>>()
+ row.iter().map(|&pat| pat_to_string(pat)).collect::<Vec<String>>()
}).collect();
let column_count = m.iter().map(|row| row.len()).max().unwrap_or(0u);
// We know the type is inhabited, so this must be wrong
cx.tcx.sess.span_err(ex.span, format!("non-exhaustive patterns: \
type {} is non-empty",
- ty_to_str(cx.tcx, pat_ty)).as_slice());
+ ty_to_string(cx.tcx, pat_ty)).as_slice());
}
// If the type *is* empty, it's vacuously exhaustive
return;
let v = vec!(*pat);
match is_useful(cx, &seen, v.as_slice(), LeaveOutWitness) {
- NotUseful => cx.tcx.sess.span_err(pat.span, "unreachable pattern"),
+ NotUseful => span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern"),
Useful => (),
UsefulWithWitness(_) => unreachable!()
}
[] => wild(),
_ => unreachable!()
};
- let msg = format!("non-exhaustive patterns: `{0}` not covered", pat_to_str(&*witness));
+ let msg = format!("non-exhaustive patterns: `{0}` not covered",
+ pat_to_string(&*witness));
cx.tcx.sess.span_err(sp, msg.as_slice());
}
NotUseful => {
};
if is_structure {
let fields = ty::lookup_struct_fields(cx.tcx, vid);
- let field_pats = fields.move_iter()
+ let field_pats: Vec<FieldPat> = fields.move_iter()
.zip(pats.iter())
+ .filter(|&(_, pat)| pat.node != PatWild)
.map(|(field, pat)| FieldPat {
ident: Ident::new(field.name),
pat: pat.clone()
}).collect();
- PatStruct(def_to_path(cx.tcx, vid), field_pats, false)
+ let has_more_fields = field_pats.len() < pats.len();
+ PatStruct(def_to_path(cx.tcx, vid), field_pats, has_more_fields)
} else {
PatEnum(def_to_path(cx.tcx, vid), Some(pats))
}
return NotUseful;
}
let real_pat = match rows.iter().find(|r| r.get(0).id != 0) {
- Some(r) => {
- match r.get(0).node {
- // An arm of the form `ref x @ sub_pat` has type
- // `sub_pat`, not `&sub_pat` as `x` itself does.
- PatIdent(BindByRef(_), _, Some(sub)) => sub,
- _ => *r.get(0)
- }
- }
+ Some(r) => raw_pat(*r.get(0)),
None if v.len() == 0 => return NotUseful,
None => v[0]
};
ty::ty_rptr(_, ty::mt { ty: ty, .. }) => match ty::get(ty).sty {
ty::ty_vec(_, None) => match *ctor {
Slice(length) => length,
+ ConstantValue(_) => 0u,
_ => unreachable!()
},
ty::ty_str => 0u,
} else {
None
},
- DefStruct(struct_id) => Some(struct_id),
- _ => None
+ _ => {
+ // Assume this is a struct.
+ match ty::ty_to_def_id(node_id_to_type(cx.tcx, pat_id)) {
+ None => {
+ cx.tcx.sess.span_bug(pat_span,
+ "struct pattern wasn't of a \
+ type with a def ID?!")
+ }
+ Some(def_id) => Some(def_id),
+ }
+ }
};
class_id.map(|variant_id| {
let struct_fields = ty::lookup_struct_fields(cx.tcx, variant_id);
Some(pat) => {
let msg = format!(
"refutable pattern in {} binding: `{}` not covered",
- name, pat_to_str(&*pat)
+ name, pat_to_string(&*pat)
);
cx.tcx.sess.span_err(loc.pat.span, msg.as_slice());
},
Some(pat) => {
let msg = format!(
"refutable pattern in function argument: `{}` not covered",
- pat_to_str(&*pat)
+ pat_to_string(&*pat)
);
cx.tcx.sess.span_err(input.pat.span, msg.as_slice());
},
impl<'a> Visitor<bool> for CheckStaticVisitor<'a> {
fn visit_item(&mut self, i: &ast::Item, _is_const: bool) {
- debug!("visit_item(item={})", pprust::item_to_str(i));
+ debug!("visit_item(item={})", pprust::item_to_string(i));
match i.node {
ast::ItemStatic(_, mutability, ref expr) => {
match mutability {
/// of a static item, this method does nothing but walking
/// down through it.
fn visit_expr(&mut self, e: &ast::Expr, is_const: bool) {
- debug!("visit_expr(expr={})", pprust::expr_to_str(e));
+ debug!("visit_expr(expr={})", pprust::expr_to_string(e));
if !is_const {
return visit::walk_expr(self, e, is_const);
use syntax::print::{pp, pprust};
use util::nodemap::NodeMap;
+#[deriving(Show)]
+pub enum EntryOrExit { Entry, Exit }
+
#[deriving(Clone)]
pub struct DataFlowContext<'a, O> {
tcx: &'a ty::ctxt,
}
impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
- fn has_bitset(&self, n: ast::NodeId) -> bool {
+ fn has_bitset_for_nodeid(&self, n: ast::NodeId) -> bool {
assert!(n != ast::DUMMY_NODE_ID);
match self.nodeid_to_index.find(&n) {
None => false,
- Some(&cfgidx) => {
- let node_id = cfgidx.node_id();
- node_id < self.index_to_bitset.len() &&
- self.index_to_bitset.get(node_id).is_some()
- }
+ Some(&cfgidx) => self.has_bitset_for_cfgidx(cfgidx),
}
}
+ fn has_bitset_for_cfgidx(&self, cfgidx: CFGIndex) -> bool {
+ let node_id = cfgidx.node_id();
+ node_id < self.index_to_bitset.len() &&
+ self.index_to_bitset.get(node_id).is_some()
+ }
fn get_bitset_index(&self, cfgidx: CFGIndex) -> uint {
let node_id = cfgidx.node_id();
self.index_to_bitset.get(node_id).unwrap()
pprust::NodePat(pat) => pat.id
};
- if self.has_bitset(id) {
+ if self.has_bitset_for_nodeid(id) {
let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
let (start, end) = self.compute_id_range_frozen(cfgidx);
let on_entry = self.on_entry.slice(start, end);
- let entry_str = bits_to_str(on_entry);
+ let entry_str = bits_to_string(on_entry);
let gens = self.gens.slice(start, end);
let gens_str = if gens.iter().any(|&u| u != 0) {
- format!(" gen: {}", bits_to_str(gens))
+ format!(" gen: {}", bits_to_string(gens))
} else {
"".to_string()
};
let kills = self.kills.slice(start, end);
let kills_str = if kills.iter().any(|&u| u != 0) {
- format!(" kill: {}", bits_to_str(kills))
+ format!(" kill: {}", bits_to_string(kills))
} else {
"".to_string()
};
}
fn apply_gen_kill(&mut self, cfgidx: CFGIndex, bits: &mut [uint]) {
- //! Applies the gen and kill sets for `id` to `bits`
+ //! Applies the gen and kill sets for `cfgidx` to `bits`
debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [before]",
- self.analysis_name, cfgidx, mut_bits_to_str(bits));
+ self.analysis_name, cfgidx, mut_bits_to_string(bits));
let (start, end) = self.compute_id_range(cfgidx);
let gens = self.gens.slice(start, end);
bitwise(bits, gens, &Union);
bitwise(bits, kills, &Subtract);
debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [after]",
- self.analysis_name, cfgidx, mut_bits_to_str(bits));
+ self.analysis_name, cfgidx, mut_bits_to_string(bits));
+ }
+
+ fn apply_gen_kill_frozen(&self, cfgidx: CFGIndex, bits: &mut [uint]) {
+ //! Applies the gen and kill sets for `cfgidx` to `bits`
+ //! Only useful after `propagate()` has been called.
+ debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [before]",
+ self.analysis_name, cfgidx, mut_bits_to_string(bits));
+ let (start, end) = self.compute_id_range_frozen(cfgidx);
+ let gens = self.gens.slice(start, end);
+ bitwise(bits, gens, &Union);
+ let kills = self.kills.slice(start, end);
+ bitwise(bits, kills, &Subtract);
+
+ debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [after]",
+ self.analysis_name, cfgidx, mut_bits_to_string(bits));
}
fn compute_id_range_frozen(&self, cfgidx: CFGIndex) -> (uint, uint) {
-> bool {
//! Iterates through each bit that is set on entry to `id`.
//! Only useful after `propagate()` has been called.
- if !self.has_bitset(id) {
+ if !self.has_bitset_for_nodeid(id) {
return true;
}
let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
+ self.each_bit_for_node(Entry, cfgidx, f)
+ }
+
+ pub fn each_bit_for_node(&self,
+ e: EntryOrExit,
+ cfgidx: CFGIndex,
+ f: |uint| -> bool)
+ -> bool {
+ //! Iterates through each bit that is set on entry/exit to `cfgidx`.
+ //! Only useful after `propagate()` has been called.
+ if !self.has_bitset_for_cfgidx(cfgidx) {
+ return true;
+ }
let (start, end) = self.compute_id_range_frozen(cfgidx);
let on_entry = self.on_entry.slice(start, end);
- debug!("{:s} each_bit_on_entry_frozen(id={:?}, on_entry={})",
- self.analysis_name, id, bits_to_str(on_entry));
- self.each_bit(on_entry, f)
+ let temp_bits;
+ let slice = match e {
+ Entry => on_entry,
+ Exit => {
+ let mut t = on_entry.to_owned();
+ self.apply_gen_kill_frozen(cfgidx, t.as_mut_slice());
+ temp_bits = t;
+ temp_bits.as_slice()
+ }
+ };
+ debug!("{:s} each_bit_for_node({}, cfgidx={}) bits={}",
+ self.analysis_name, e, cfgidx, bits_to_string(slice));
+ self.each_bit(slice, f)
}
pub fn each_gen_bit_frozen(&self, id: ast::NodeId, f: |uint| -> bool)
-> bool {
//! Iterates through each bit in the gen set for `id`.
- if !self.has_bitset(id) {
+ //! Only useful after `propagate()` has been called.
+ if !self.has_bitset_for_nodeid(id) {
return true;
}
let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
let (start, end) = self.compute_id_range_frozen(cfgidx);
let gens = self.gens.slice(start, end);
debug!("{:s} each_gen_bit(id={:?}, gens={})",
- self.analysis_name, id, bits_to_str(gens));
+ self.analysis_name, id, bits_to_string(gens));
self.each_bit(gens, f)
}
if changed {
let bits = self.kills.mut_slice(start, end);
debug!("{:s} add_kills_from_flow_exits flow_exit={} bits={} [before]",
- self.analysis_name, flow_exit, mut_bits_to_str(bits));
+ self.analysis_name, flow_exit, mut_bits_to_string(bits));
bits.copy_from(orig_kills.as_slice());
debug!("{:s} add_kills_from_flow_exits flow_exit={} bits={} [after]",
- self.analysis_name, flow_exit, mut_bits_to_str(bits));
+ self.analysis_name, flow_exit, mut_bits_to_string(bits));
}
true
});
cfg: &cfg::CFG,
in_out: &mut [uint]) {
debug!("DataFlowContext::walk_cfg(in_out={}) {:s}",
- bits_to_str(in_out), self.dfcx.analysis_name);
+ bits_to_string(in_out), self.dfcx.analysis_name);
cfg.graph.each_node(|node_index, node| {
debug!("DataFlowContext::walk_cfg idx={} id={} begin in_out={}",
- node_index, node.data.id, bits_to_str(in_out));
+ node_index, node.data.id, bits_to_string(in_out));
let (start, end) = self.dfcx.compute_id_range(node_index);
let source = edge.source();
let cfgidx = edge.target();
debug!("{:s} propagate_bits_into_entry_set_for(pred_bits={}, {} to {})",
- self.dfcx.analysis_name, bits_to_str(pred_bits), source, cfgidx);
+ self.dfcx.analysis_name, bits_to_string(pred_bits), source, cfgidx);
let (start, end) = self.dfcx.compute_id_range(cfgidx);
let changed = {
// (scoping mutable borrow of self.dfcx.on_entry)
if changed {
debug!("{:s} changed entry set for {:?} to {}",
self.dfcx.analysis_name, cfgidx,
- bits_to_str(self.dfcx.on_entry.slice(start, end)));
+ bits_to_string(self.dfcx.on_entry.slice(start, end)));
self.changed = true;
}
}
}
-fn mut_bits_to_str(words: &mut [uint]) -> String {
- bits_to_str(words)
+fn mut_bits_to_string(words: &mut [uint]) -> String {
+ bits_to_string(words)
}
-fn bits_to_str(words: &[uint]) -> String {
+fn bits_to_string(words: &[uint]) -> String {
let mut result = String::new();
let mut sep = '[';
fn set_bit(words: &mut [uint], bit: uint) -> bool {
debug!("set_bit: words={} bit={}",
- mut_bits_to_str(words), bit_str(bit));
+ mut_bits_to_string(words), bit_str(bit));
let word = bit / uint::BITS;
let bit_in_word = bit % uint::BITS;
let bit_mask = 1 << bit_in_word;
use std::collections::HashSet;
use syntax::ast;
use syntax::ast_map;
+use syntax::ast_util;
use syntax::ast_util::{local_def, is_local};
use syntax::attr::AttrMetaMethods;
use syntax::attr;
}
fn handle_field_pattern_match(&mut self, lhs: &ast::Pat, pats: &[ast::FieldPat]) {
- match self.tcx.def_map.borrow().get(&lhs.id) {
- &def::DefStruct(id) | &def::DefVariant(_, id, _) => {
- let fields = ty::lookup_struct_fields(self.tcx, id);
- for pat in pats.iter() {
- let field_id = fields.iter()
- .find(|field| field.name == pat.ident.name).unwrap().id;
- self.live_symbols.insert(field_id.node);
+ let id = match self.tcx.def_map.borrow().get(&lhs.id) {
+ &def::DefVariant(_, id, _) => id,
+ _ => {
+ match ty::ty_to_def_id(ty::node_id_to_type(self.tcx,
+ lhs.id)) {
+ None => {
+ self.tcx.sess.span_bug(lhs.span,
+ "struct pattern wasn't of a \
+ type with a def ID?!")
+ }
+ Some(def_id) => def_id,
}
}
- _ => ()
+ };
+ let fields = ty::lookup_struct_fields(self.tcx, id);
+ for pat in pats.iter() {
+ let field_id = fields.iter()
+ .find(|field| field.name == pat.ident.name).unwrap().id;
+ self.live_symbols.insert(field_id.node);
}
}
visit::walk_trait_method(self, &*trait_method, ctxt);
}
ast_map::NodeMethod(method) => {
- visit::walk_block(self, &*method.body, ctxt);
+ visit::walk_block(self, ast_util::method_body(&*method), ctxt);
}
ast_map::NodeForeignItem(foreign_item) => {
visit::walk_foreign_item(self, &*foreign_item, ctxt);
// Overwrite so that we don't warn the trait method itself.
fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
match *trait_method {
- ast::Provided(ref method) => visit::walk_block(self, &*method.body, ()),
+ ast::Provided(ref method) => visit::walk_block(self,
+ ast_util::method_body(&**method), ()),
ast::Required(_) => ()
}
}
use util::ppaux;
use syntax::ast;
+use syntax::ast_util;
use syntax::codemap::Span;
use syntax::visit;
use syntax::visit::Visitor;
_ => return
};
debug!("effect: checking index with base type {}",
- ppaux::ty_to_str(self.tcx, base_type));
+ ppaux::ty_to_string(self.tcx, base_type));
match ty::get(base_type).sty {
ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
ty::ty_str => {
visit::FkItemFn(_, _, fn_style, _) =>
(true, fn_style == ast::UnsafeFn),
visit::FkMethod(_, _, method) =>
- (true, method.fn_style == ast::UnsafeFn),
+ (true, ast_util::method_fn_style(method) == ast::UnsafeFn),
_ => (false, false),
};
let method_call = MethodCall::expr(expr.id);
let base_type = self.tcx.method_map.borrow().get(&method_call).ty;
debug!("effect: method call case, base type is {}",
- ppaux::ty_to_str(self.tcx, base_type));
+ ppaux::ty_to_string(self.tcx, base_type));
if type_is_unsafe_function(base_type) {
self.require_unsafe(expr.span,
"invocation of unsafe method")
ast::ExprCall(base, _) => {
let base_type = ty::node_id_to_type(self.tcx, base.id);
debug!("effect: call case, base type is {}",
- ppaux::ty_to_str(self.tcx, base_type));
+ ppaux::ty_to_string(self.tcx, base_type));
if type_is_unsafe_function(base_type) {
self.require_unsafe(expr.span, "call to unsafe function")
}
ast::ExprUnary(ast::UnDeref, base) => {
let base_type = ty::node_id_to_type(self.tcx, base.id);
debug!("effect: unary case, base type is {}",
- ppaux::ty_to_str(self.tcx, base_type));
+ ppaux::ty_to_string(self.tcx, base_type));
match ty::get(base_type).sty {
ty::ty_ptr(_) => {
self.require_unsafe(expr.span,
pub fn each_node<'a>(&'a self, f: |NodeIndex, &'a Node<N>| -> bool) -> bool {
//! Iterates over all edges defined in the graph.
- self.nodes.iter().enumerate().advance(|(i, node)| f(NodeIndex(i), node))
+ self.nodes.iter().enumerate().all(|(i, node)| f(NodeIndex(i), node))
}
pub fn each_edge<'a>(&'a self, f: |EdgeIndex, &'a Edge<E>| -> bool) -> bool {
//! Iterates over all edges defined in the graph
- self.edges.iter().enumerate().advance(|(i, edge)| f(EdgeIndex(i), edge))
+ self.edges.iter().enumerate().all(|(i, edge)| f(EdgeIndex(i), edge))
}
pub fn each_outgoing_edge<'a>(&'a self,
use middle::ty;
use middle::typeck::{MethodCall, NoAdjustment};
use middle::typeck;
-use util::ppaux::{Repr, ty_to_str};
+use util::ppaux::{Repr, ty_to_string};
use util::ppaux::UserString;
use syntax::ast::*;
use syntax::attr;
use syntax::codemap::Span;
-use syntax::print::pprust::{expr_to_str, ident_to_str};
+use syntax::print::pprust::{expr_to_string, ident_to_string};
use syntax::{visit};
use syntax::visit::Visitor;
cx.tcx.sess.span_err(self_type.span,
format!("the type `{}', which does not fulfill `{}`, cannot implement this \
trait",
- ty_to_str(cx.tcx, self_ty),
+ ty_to_string(cx.tcx, self_ty),
missing.user_string(cx.tcx)).as_slice());
cx.tcx.sess.span_note(self_type.span,
format!("types implementing this trait must fulfill `{}`",
}
pub fn check_expr(cx: &mut Context, e: &Expr) {
- debug!("kind::check_expr({})", expr_to_str(e));
+ debug!("kind::check_expr({})", expr_to_string(e));
// Handle any kind bounds on type parameters
check_bounds_on_type_parameters(cx, e);
sp,
format!("instantiating a type parameter with an incompatible type \
`{}`, which does not fulfill `{}`",
- ty_to_str(cx.tcx, ty),
+ ty_to_string(cx.tcx, ty),
missing.user_string(cx.tcx)).as_slice());
});
}
format!("cannot implicitly borrow variable of type `{}` in a \
bounded stack closure (implicit reference does not \
fulfill `{}`)",
- ty_to_str(cx.tcx, rty),
+ ty_to_string(cx.tcx, rty),
missing.user_string(cx.tcx)).as_slice())
}
None => {
cx.tcx.sess.span_err(sp,
format!("cannot capture variable of type `{}`, which does \
not fulfill `{}`, in a bounded closure",
- ty_to_str(cx.tcx, ty),
+ ty_to_string(cx.tcx, ty),
missing.user_string(cx.tcx)).as_slice())
}
}
cx.tcx.sess.span_err(sp,
format!("cannot pack type `{}`, which does not fulfill \
`{}`, as a trait bounded by {}",
- ty_to_str(cx.tcx, ty), missing.user_string(cx.tcx),
+ ty_to_string(cx.tcx, ty), missing.user_string(cx.tcx),
bounds.user_string(cx.tcx)).as_slice());
});
}
fn check_copy(cx: &Context, ty: ty::t, sp: Span, reason: &str) {
debug!("type_contents({})={}",
- ty_to_str(cx.tcx, ty),
- ty::type_contents(cx.tcx, ty).to_str());
+ ty_to_string(cx.tcx, ty),
+ ty::type_contents(cx.tcx, ty).to_string());
if ty::type_moves_by_default(cx.tcx, ty) {
cx.tcx.sess.span_err(
sp,
format!("copying a value of non-copyable type `{}`",
- ty_to_str(cx.tcx, ty)).as_slice());
+ ty_to_string(cx.tcx, ty)).as_slice());
cx.tcx.sess.span_note(sp, format!("{}", reason).as_slice());
}
}
tcx.sess.span_err(sp,
format!("value may contain references; \
add `'static` bound to `{}`",
- ty_to_str(tcx, ty)).as_slice());
+ ty_to_string(tcx, ty)).as_slice());
}
_ => {
tcx.sess.span_err(sp, "value may contain references");
// source_span,
// format!("source contains reference with lifetime \
// not found in the target type `{}`",
- // ty_to_str(cx.tcx, target_ty)));
+ // ty_to_string(cx.tcx, target_ty)));
// note_and_explain_region(
// cx.tcx, "source data is only valid for ", r, "");
// }
format!("variable `{}` has dynamically sized type \
`{}`",
name,
- ty_to_str(tcx, ty)).as_slice());
+ ty_to_string(tcx, ty)).as_slice());
}
}
fn check_pat(cx: &mut Context, pat: &Pat) {
let var_name = match pat.node {
PatWild => Some("_".to_string()),
- PatIdent(_, ref path1, _) => Some(ident_to_str(&path1.node).to_string()),
+ PatIdent(_, ref path1, _) => Some(ident_to_string(&path1.node).to_string()),
_ => None
};
match ty {
Some(ty) => {
debug!("kind: checking sized-ness of variable {}: {}",
- name, ty_to_str(cx.tcx, *ty));
+ name, ty_to_string(cx.tcx, *ty));
check_sized(cx.tcx, *ty, name, pat.span);
}
None => {} // extern fn args
ShlTraitLangItem, "shl", shl_trait;
ShrTraitLangItem, "shr", shr_trait;
IndexTraitLangItem, "index", index_trait;
+ IndexMutTraitLangItem, "index_mut", index_mut_trait;
UnsafeTypeLangItem, "unsafe", unsafe_type;
use syntax::codemap::{BytePos, original_sp, Span};
use syntax::parse::token::special_idents;
use syntax::parse::token;
-use syntax::print::pprust::{expr_to_str, block_to_str};
+use syntax::print::pprust::{expr_to_string, block_to_string};
use syntax::{visit, ast_util};
use syntax::visit::{Visitor, FnKind};
ExitNode
}
-fn live_node_kind_to_str(lnk: LiveNodeKind, cx: &ty::ctxt) -> String {
+fn live_node_kind_to_string(lnk: LiveNodeKind, cx: &ty::ctxt) -> String {
let cm = cx.sess.codemap();
match lnk {
FreeVarNode(s) => {
- format!("Free var node [{}]", cm.span_to_str(s))
+ format!("Free var node [{}]", cm.span_to_string(s))
}
ExprNode(s) => {
- format!("Expr node [{}]", cm.span_to_str(s))
+ format!("Expr node [{}]", cm.span_to_string(s))
}
VarDefNode(s) => {
- format!("Var def node [{}]", cm.span_to_str(s))
+ format!("Var def node [{}]", cm.span_to_string(s))
}
ExitNode => "Exit node".to_string(),
}
self.lnks.push(lnk);
self.num_live_nodes += 1;
- debug!("{} is of kind {}", ln.to_str(),
- live_node_kind_to_str(lnk, self.tcx));
+ debug!("{} is of kind {}", ln.to_string(),
+ live_node_kind_to_string(lnk, self.tcx));
ln
}
let ln = self.add_live_node(lnk);
self.live_node_map.insert(node_id, ln);
- debug!("{} is node {}", ln.to_str(), node_id);
+ debug!("{} is node {}", ln.to_string(), node_id);
}
fn add_variable(&mut self, vk: VarKind) -> Variable {
ImplicitRet => {}
}
- debug!("{} is {:?}", v.to_str(), vk);
+ debug!("{} is {:?}", v.to_string(), vk);
v
}
fn variable_name(&self, var: Variable) -> String {
match self.var_kinds.get(var.get()) {
&Local(LocalInfo { ident: nm, .. }) | &Arg(_, nm) => {
- token::get_ident(nm).get().to_str()
+ token::get_ident(nm).get().to_string()
},
&ImplicitRet => "<implicit-ret>".to_string()
}
for var_idx in range(0u, self.ir.num_vars) {
let idx = node_base_idx + var_idx;
if test(idx).is_valid() {
- try!(write!(wr, " {}", Variable(var_idx).to_str()));
+ try!(write!(wr, " {}", Variable(var_idx).to_string()));
}
}
Ok(())
self.write_vars(wr, ln, |idx| self.users.get(idx).reader);
write!(wr, " writes");
self.write_vars(wr, ln, |idx| self.users.get(idx).writer);
- write!(wr, " precedes {}]", self.successors.get(ln.get()).to_str());
+ write!(wr, " precedes {}]", self.successors.get(ln.get()).to_string());
}
str::from_utf8(wr.unwrap().as_slice()).unwrap().to_string()
}
});
debug!("merge_from_succ(ln={}, succ={}, first_merge={}, changed={})",
- ln.to_str(), self.ln_str(succ_ln), first_merge, changed);
+ ln.to_string(), self.ln_str(succ_ln), first_merge, changed);
return changed;
fn copy_if_invalid(src: LiveNode, dst: &mut LiveNode) -> bool {
self.users.get_mut(idx).reader = invalid_node();
self.users.get_mut(idx).writer = invalid_node();
- debug!("{} defines {} (idx={}): {}", writer.to_str(), var.to_str(),
+ debug!("{} defines {} (idx={}): {}", writer.to_string(), var.to_string(),
idx, self.ln_str(writer));
}
// Either read, write, or both depending on the acc bitset
fn acc(&mut self, ln: LiveNode, var: Variable, acc: uint) {
debug!("{} accesses[{:x}] {}: {}",
- ln.to_str(), acc, var.to_str(), self.ln_str(ln));
+ ln.to_string(), acc, var.to_string(), self.ln_str(ln));
let idx = self.idx(ln, var);
let user = self.users.get_mut(idx);
// effectively a return---this only occurs in `for` loops,
// where the body is really a closure.
- debug!("compute: using id for block, {}", block_to_str(body));
+ debug!("compute: using id for block, {}", block_to_string(body));
let exit_ln = self.s.exit_ln;
let entry_ln: LiveNode =
}
body.id
},
- entry_ln.to_str());
+ entry_ln.to_string());
entry_ln
}
fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
-> LiveNode {
- debug!("propagate_through_expr: {}", expr_to_str(expr));
+ debug!("propagate_through_expr: {}", expr_to_string(expr));
match expr.node {
// Interesting cases with control flow or which gen/kill
}
ExprFnBlock(_, ref blk) | ExprProc(_, ref blk) => {
- debug!("{} is an ExprFnBlock or ExprProc", expr_to_str(expr));
+ debug!("{} is an ExprFnBlock or ExprProc", expr_to_string(expr));
/*
The next-node for a break is the successor of the entire
first_merge = false;
}
debug!("propagate_through_loop: using id for loop body {} {}",
- expr.id, block_to_str(body));
+ expr.id, block_to_string(body));
let cond_ln = self.propagate_through_opt_expr(cond, ln);
let body_ln = self.with_loop_nodes(expr.id, succ, ln, |this| {
},
_ => false
};
+ self.ir.tcx.sess.span_err(
+ sp, "not all control paths return a value");
if ends_with_stmt {
let last_stmt = body.stmts.last().unwrap();
let original_span = original_sp(last_stmt.span, sp);
self.ir.tcx.sess.span_note(
span_semicolon, "consider removing this semicolon:");
}
- self.ir.tcx.sess.span_err(
- sp, "not all control paths return a value");
}
}
}
use middle::ty;
use middle::typeck;
use util::nodemap::NodeMap;
-use util::ppaux::{ty_to_str, Repr};
+use util::ppaux::{ty_to_string, Repr};
use syntax::ast::{MutImmutable, MutMutable};
use syntax::ast;
None => {
tcx.sess.bug(
format!("deref_cat() invoked on non-derefable type {}",
- ty_to_str(tcx, t)).as_slice());
+ ty_to_string(tcx, t)).as_slice());
}
}
}
}
ast::ExprIndex(ref base, _) => {
- if self.typer.is_method_call(expr.id) {
- return Ok(self.cat_rvalue_node(expr.id(), expr.span(), expr_ty));
- }
-
let base_cmt = if_ok!(self.cat_expr(&**base));
Ok(self.cat_index(expr, base_cmt, 0))
}
pub fn cat_index<N:ast_node>(&self,
elt: &N,
- base_cmt: cmt,
+ mut base_cmt: cmt,
derefs: uint)
-> cmt {
//! Creates a cmt for an indexing operation (`[]`); this
//! - `derefs`: the deref number to be used for
//! the implicit index deref, if any (see above)
- let element_ty = match ty::array_element_ty(base_cmt.ty) {
- Some(ref mt) => mt.ty,
- None => {
- self.tcx().sess.span_bug(
- elt.span(),
- format!("Explicit index of non-index type `{}`",
- base_cmt.ty.repr(self.tcx())).as_slice());
- }
+ let method_call = typeck::MethodCall::expr(elt.id());
+ let method_ty = self.typer.node_method_ty(method_call);
+
+ let element_ty = match method_ty {
+ Some(method_ty) => {
+ let ref_ty = ty::ty_fn_ret(method_ty);
+ base_cmt = self.cat_rvalue_node(elt.id(), elt.span(), ref_ty);
+ *ty::ty_fn_args(method_ty).get(0)
+ }
+ None => {
+ match ty::array_element_ty(base_cmt.ty) {
+ Some(ref mt) => mt.ty,
+ None => {
+ self.tcx().sess.span_bug(
+ elt.span(),
+ format!("Explicit index of non-index type `{}`",
+ base_cmt.ty.repr(self.tcx())).as_slice());
+ }
+ }
+ }
};
return match deref_kind(self.tcx(), base_cmt.ty) {
// get the type of the *subpattern* and use that.
debug!("cat_pattern: id={} pat={} cmt={}",
- pat.id, pprust::pat_to_str(pat),
+ pat.id, pprust::pat_to_string(pat),
cmt.repr(self.tcx()));
op(self, cmt.clone(), pat);
Ok(())
}
- pub fn cmt_to_str(&self, cmt: &cmt_) -> String {
+ pub fn cmt_to_string(&self, cmt: &cmt_) -> String {
match cmt.cat {
cat_static_item => {
"static item".to_string()
"captured outer variable".to_string()
}
cat_discr(ref cmt, _) => {
- self.cmt_to_str(&**cmt)
+ self.cmt_to_string(&**cmt)
}
cat_downcast(ref cmt) => {
- self.cmt_to_str(&**cmt)
+ self.cmt_to_string(&**cmt)
}
}
}
fn repr(&self, _tcx: &ty::ctxt) -> String {
match *self {
InteriorField(NamedField(fld)) => {
- token::get_name(fld).get().to_str()
+ token::get_name(fld).get().to_string()
}
InteriorField(PositionalField(i)) => format!("#{:?}", i),
InteriorElement(_) => "[]".to_string(),
use syntax::ast;
use syntax::ast_map;
+use syntax::ast_util;
use syntax::ast_util::{is_local, local_def};
use syntax::attr;
use syntax::codemap::Span;
if public_ty || public_trait {
for method in methods.iter() {
- let meth_public = match method.explicit_self.node {
+ let meth_public = match ast_util::method_explicit_self(&**method).node {
ast::SelfStatic => public_ty,
_ => true,
- } && method.vis == ast::Public;
+ } && ast_util::method_vis(&**method) == ast::Public;
if meth_public || tr.is_some() {
self.exported_items.insert(method.id);
}
impl<'a> PrivacyVisitor<'a> {
// used when debugging
fn nodestr(&self, id: ast::NodeId) -> String {
- self.tcx.map.node_to_str(id).to_string()
+ self.tcx.map.node_to_string(id).to_string()
}
// Determines whether the given definition is public from the point of view
}
debug!("privacy - local {} not public all the way down",
- self.tcx.map.node_to_str(did.node));
+ self.tcx.map.node_to_string(did.node));
// return quickly for things in the same module
if self.parents.find(&did.node) == self.parents.find(&self.curitem) {
debug!("privacy - same parent, we're done here");
let imp = self.tcx.map.get_parent_did(closest_private_id);
match ty::impl_trait_ref(self.tcx, imp) {
Some(..) => return Allowable,
- _ if m.vis == ast::Public => return Allowable,
- _ => m.vis
+ _ if ast_util::method_vis(&**m) == ast::Public => return Allowable,
+ _ => ast_util::method_vis(&**m)
}
}
Some(ast_map::NodeTraitMethod(_)) => {
"visibility qualifiers have no effect on trait \
impls");
for m in methods.iter() {
- check_inherited(m.span, m.vis, "");
+ check_inherited(m.span, ast_util::method_vis(&**m), "");
}
}
for m in methods.iter() {
match *m {
ast::Provided(ref m) => {
- check_inherited(m.span, m.vis,
+ check_inherited(m.span, ast_util::method_vis(&**m),
"unnecessary visibility");
}
ast::Required(ref m) => {
match item.node {
ast::ItemImpl(_, _, _, ref methods) => {
for m in methods.iter() {
- check_inherited(tcx, m.span, m.vis);
+ check_inherited(tcx, m.span, ast_util::method_vis(&**m));
}
}
ast::ItemForeignMod(ref fm) => {
match *m {
ast::Required(..) => {}
ast::Provided(ref m) => check_inherited(tcx, m.span,
- m.vis),
+ ast_util::method_vis(&**m)),
}
}
}
// methods will be visible as `Public::foo`.
let mut found_pub_static = false;
for method in methods.iter() {
- if method.explicit_self.node == ast::SelfStatic &&
+ if ast_util::method_explicit_self(&**method).node == ast::SelfStatic &&
self.exported_items.contains(&method.id) {
found_pub_static = true;
visit::walk_method_helper(self, &**method, ());
fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method,
impl_src: ast::DefId) -> bool {
if attributes_specify_inlining(method.attrs.as_slice()) ||
- generics_require_inlining(&method.generics) {
+ generics_require_inlining(ast_util::method_generics(&*method)) {
return true
}
if is_local(impl_src) {
}
}
Some(ast_map::NodeMethod(method)) => {
- if generics_require_inlining(&method.generics) ||
+ if generics_require_inlining(ast_util::method_generics(&*method)) ||
attributes_specify_inlining(method.attrs.as_slice()) {
true
} else {
// Keep going, nothing to get exported
}
ast::Provided(ref method) => {
- visit::walk_block(self, &*method.body, ())
+ visit::walk_block(self, ast_util::method_body(&**method), ())
}
}
}
ast_map::NodeMethod(method) => {
let did = self.tcx.map.get_parent_did(search_item);
if method_might_be_inlined(self.tcx, &*method, did) {
- visit::walk_block(self, &*method.body, ())
+ visit::walk_block(self, ast_util::method_body(&*method), ())
}
}
// Nothing to recurse on for these
.bug(format!("found unexpected thingy in worklist: {}",
self.tcx
.map
- .node_to_str(search_item)).as_slice())
+ .node_to_string(search_item)).as_slice())
}
}
}
body.id={}, \
cx.parent={})",
id,
- visitor.sess.codemap().span_to_str(sp),
+ visitor.sess.codemap().span_to_string(sp),
body.id,
cx.parent);
use syntax::ast::*;
use syntax::ast;
+use syntax::ast_util;
use syntax::ast_util::{local_def};
use syntax::ast_util::{walk_pat, trait_method_to_ty_method};
use syntax::ext::mtwt;
+use syntax::parse::token::special_names;
use syntax::parse::token::special_idents;
use syntax::parse::token;
use syntax::codemap::{Span, DUMMY_SP, Pos};
#[deriving(PartialEq)]
enum DuplicateCheckingMode {
ForbidDuplicateModules,
- ForbidDuplicateTypes,
+ ForbidDuplicateTypesAndModules,
ForbidDuplicateValues,
ForbidDuplicateTypesAndValues,
OverwriteDuplicates
}
-fn namespace_error_to_str(ns: NamespaceError) -> &'static str {
+fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
match ns {
- NoError => "",
- ModuleError => "module",
- TypeError => "type",
- ValueError => "value",
+ NoError => "",
+ ModuleError | TypeError => "type or module",
+ ValueError => "value",
}
}
current_self_type: Option<Ty>,
// The ident for the keyword "self".
- self_ident: Ident,
+ self_name: Name,
// The ident for the non-keyword "Self".
- type_self_ident: Ident,
+ type_self_name: Name,
// The idents for the primitive types.
primitive_type_table: PrimitiveTypeTable,
current_trait_ref: None,
current_self_type: None,
- self_ident: special_idents::self_,
- type_self_ident: special_idents::type_self,
+ self_name: special_names::self_,
+ type_self_name: special_names::type_self,
primitive_type_table: PrimitiveTypeTable::new(),
}
Some(TypeNS)
}
- ForbidDuplicateTypes => {
+ ForbidDuplicateTypesAndModules => {
match child.def_for_namespace(TypeNS) {
- Some(DefMod(_)) | None => {}
+ None => {}
+ Some(_) if child.get_module_if_available()
+ .map(|m| m.kind.get()) ==
+ Some(ImplModuleKind) => {}
Some(_) => duplicate_type = TypeError
}
Some(TypeNS)
let ns = ns.unwrap();
self.resolve_error(sp,
format!("duplicate definition of {} `{}`",
- namespace_error_to_str(duplicate_type),
+ namespace_error_to_string(duplicate_type),
token::get_ident(name)).as_slice());
{
let r = child.span_for_namespace(ns);
for sp in r.iter() {
self.session.span_note(*sp,
format!("first definition of {} `{}` here",
- namespace_error_to_str(duplicate_type),
+ namespace_error_to_string(duplicate_type),
token::get_ident(name)).as_slice());
}
}
// These items live in the type namespace.
ItemTy(..) => {
let name_bindings =
- self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp);
+ self.add_child(ident,
+ parent.clone(),
+ ForbidDuplicateTypesAndModules,
+ sp);
name_bindings.define_type
(DefTy(local_def(item.id)), sp, is_public);
ItemEnum(ref enum_definition, _) => {
let name_bindings =
- self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp);
+ self.add_child(ident,
+ parent.clone(),
+ ForbidDuplicateTypesAndModules,
+ sp);
name_bindings.define_type
(DefTy(local_def(item.id)), sp, is_public);
// Adding to both Type and Value namespaces or just Type?
let (forbid, ctor_id) = match struct_def.ctor_id {
Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
- None => (ForbidDuplicateTypes, None)
+ None => (ForbidDuplicateTypesAndModules, None)
};
let name_bindings = self.add_child(ident, parent.clone(), forbid, sp);
// For each method...
for method in methods.iter() {
// Add the method to the module.
- let ident = method.ident;
+ let ident = ast_util::method_ident(&**method);
let method_name_bindings =
self.add_child(ident,
new_parent.clone(),
ForbidDuplicateValues,
method.span);
- let def = match method.explicit_self.node {
+ let def = match ast_util::method_explicit_self(&**method).node {
SelfStatic => {
// Static methods become
// `def_static_method`s.
DefStaticMethod(local_def(method.id),
FromImpl(local_def(
item.id)),
- method.fn_style)
+ ast_util::method_fn_style(&**method))
}
_ => {
// Non-static methods become
}
};
- let is_public = method.vis == ast::Public;
+ let is_public = ast_util::method_vis(&**method) == ast::Public;
method_name_bindings.define_value(def,
method.span,
is_public);
ItemTrait(_, _, _, ref methods) => {
let name_bindings =
- self.add_child(ident, parent.clone(), ForbidDuplicateTypes, sp);
+ self.add_child(ident,
+ parent.clone(),
+ ForbidDuplicateTypesAndModules,
+ sp);
// Add all the methods within to a new module.
let parent_link = self.get_parent_link(parent.clone(), ident);
false,
true));
debug!("(build reduced graph for item) found extern `{}`",
- self.module_to_str(&*external_module));
+ self.module_to_string(&*external_module));
parent.module().external_module_children.borrow_mut()
.insert(name.name, external_module.clone());
self.build_reduced_graph_for_external_crate(external_module);
/// Builds the reduced graph rooted at the given external module.
fn populate_external_module(&mut self, module: Rc<Module>) {
debug!("(populating external module) attempting to populate {}",
- self.module_to_str(&*module));
+ self.module_to_string(&*module));
let def_id = match module.def_id.get() {
None => {
SingleImport(target, _) => {
debug!("(building import directive) building import \
directive: {}::{}",
- self.idents_to_str(module_.imports.borrow().last().unwrap()
+ self.idents_to_string(module_.imports.borrow().last().unwrap()
.module_path.as_slice()),
token::get_ident(target));
/// submodules.
fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
debug!("(resolving imports for module subtree) resolving {}",
- self.module_to_str(&*module_));
+ self.module_to_string(&*module_));
let orig_module = replace(&mut self.current_module, module_.clone());
self.resolve_imports_for_module(module_.clone());
self.current_module = orig_module;
if module.all_imports_resolved() {
debug!("(resolving imports for module) all imports resolved for \
{}",
- self.module_to_str(&*module));
+ self.module_to_string(&*module));
return;
}
None => (import_directive.span, String::new())
};
let msg = format!("unresolved import `{}`{}",
- self.import_path_to_str(
+ self.import_path_to_string(
import_directive.module_path
.as_slice(),
import_directive.subclass),
}
}
- fn idents_to_str(&self, idents: &[Ident]) -> String {
+ fn idents_to_string(&self, idents: &[Ident]) -> String {
let mut first = true;
let mut result = String::new();
for ident in idents.iter() {
result
}
- fn path_idents_to_str(&self, path: &Path) -> String {
+ fn path_idents_to_string(&self, path: &Path) -> String {
let identifiers: Vec<ast::Ident> = path.segments
.iter()
.map(|seg| seg.identifier)
.collect();
- self.idents_to_str(identifiers.as_slice())
+ self.idents_to_string(identifiers.as_slice())
}
- fn import_directive_subclass_to_str(&mut self,
+ fn import_directive_subclass_to_string(&mut self,
subclass: ImportDirectiveSubclass)
-> String {
match subclass {
}
}
- fn import_path_to_str(&mut self,
+ fn import_path_to_string(&mut self,
idents: &[Ident],
subclass: ImportDirectiveSubclass)
-> String {
if idents.is_empty() {
- self.import_directive_subclass_to_str(subclass)
+ self.import_directive_subclass_to_string(subclass)
} else {
(format!("{}::{}",
- self.idents_to_str(idents),
- self.import_directive_subclass_to_str(
+ self.idents_to_string(idents),
+ self.import_directive_subclass_to_string(
subclass))).to_string()
}
}
debug!("(resolving import for module) resolving import `{}::...` in \
`{}`",
- self.idents_to_str(module_path.as_slice()),
- self.module_to_str(&*module_));
+ self.idents_to_string(module_path.as_slice()),
+ self.module_to_string(&*module_));
// First, resolve the module path for the directive, if necessary.
let container = if module_path.len() == 0 {
debug!("(resolving single import) resolving `{}` = `{}::{}` from \
`{}` id {}, last private {:?}",
token::get_ident(target),
- self.module_to_str(&*containing_module),
+ self.module_to_string(&*containing_module),
token::get_ident(source),
- self.module_to_str(module_),
+ self.module_to_string(module_),
directive.id,
lp);
if value_result.is_unbound() && type_result.is_unbound() {
let msg = format!("There is no `{}` in `{}`",
token::get_ident(source),
- self.module_to_str(&*containing_module));
+ self.module_to_string(&*containing_module));
return Failed(Some((directive.span, msg)));
}
let value_used_public = value_used_reexport || value_used_public;
debug!("(resolving glob import) writing module resolution \
{:?} into `{}`",
target_import_resolution.type_target.is_none(),
- self.module_to_str(module_));
+ self.module_to_string(module_));
if !target_import_resolution.is_public {
debug!("(resolving glob import) nevermind, just kidding");
debug!("(resolving glob import) writing resolution `{}` in `{}` \
to `{}`",
- token::get_name(name).get().to_str(),
- self.module_to_str(&*containing_module),
- self.module_to_str(module_));
+ token::get_name(name).get().to_string(),
+ self.module_to_string(&*containing_module),
+ self.module_to_string(module_));
// Merge the child item into the import resolution.
if name_bindings.defined_in_public_namespace(ValueNS) {
false) {
Failed(None) => {
let segment_name = token::get_ident(name);
- let module_name = self.module_to_str(&*search_module);
+ let module_name = self.module_to_string(&*search_module);
let mut span = span;
let msg = if "???" == module_name.as_slice() {
span.hi = span.lo + Pos::from_uint(segment_name.get().len());
match search_parent_externals(name.name,
&self.current_module) {
Some(module) => {
- let path_str = self.idents_to_str(module_path);
- let target_mod_str = self.module_to_str(&*module);
+ let path_str = self.idents_to_string(module_path);
+ let target_mod_str = self.module_to_string(&*module);
let current_mod_str =
- self.module_to_str(&*self.current_module);
+ self.module_to_string(&*self.current_module);
let prefix = if target_mod_str == current_mod_str {
"self::".to_string()
debug!("(resolving module path for import) processing `{}` rooted at \
`{}`",
- self.idents_to_str(module_path),
- self.module_to_str(&*module_));
+ self.idents_to_string(module_path),
+ self.module_to_string(&*module_));
// Resolve the module prefix, if any.
let module_prefix_result = self.resolve_module_prefix(module_.clone(),
let last_private;
match module_prefix_result {
Failed(None) => {
- let mpath = self.idents_to_str(module_path);
+ let mpath = self.idents_to_string(module_path);
let mpath = mpath.as_slice();
match mpath.rfind(':') {
Some(idx) => {
namespace {:?} in `{}`",
token::get_ident(name),
namespace,
- self.module_to_str(&*module_));
+ self.module_to_string(&*module_));
// The current module node is handled specially. First, check for
// its immediate children.
break
}
debug!("(resolving module prefix) resolving `super` at {}",
- self.module_to_str(&*containing_module));
+ self.module_to_string(&*containing_module));
match self.get_nearest_normal_module_parent(containing_module) {
None => return Failed(None),
Some(new_module) => {
}
debug!("(resolving module prefix) finished resolving prefix at {}",
- self.module_to_str(&*containing_module));
+ self.module_to_string(&*containing_module));
return Success(PrefixFound(containing_module, i));
}
-> ResolveResult<(Target, bool)> {
debug!("(resolving name in module) resolving `{}` in `{}`",
token::get_name(name).get(),
- self.module_to_str(&*module_));
+ self.module_to_string(&*module_));
// First, check the direct children of the module.
self.populate_module_if_necessary(&module_);
// OK. Continue.
debug!("(recording exports for module subtree) recording \
exports for local module `{}`",
- self.module_to_str(&*module_));
+ self.module_to_string(&*module_));
}
None => {
// Record exports for the root module.
debug!("(recording exports for module subtree) recording \
exports for root module `{}`",
- self.module_to_str(&*module_));
+ self.module_to_string(&*module_));
}
Some(_) => {
// Bail out.
debug!("(recording exports for module subtree) not recording \
exports for `{}`",
- self.module_to_str(&*module_));
+ self.module_to_string(&*module_));
return;
}
}
None => {
debug!("!!! (with scope) didn't find `{}` in `{}`",
token::get_ident(name),
- self.module_to_str(&*orig_module));
+ self.module_to_string(&*orig_module));
}
Some(name_bindings) => {
match (*name_bindings).get_module_if_available() {
debug!("!!! (with scope) didn't find module \
for `{}` in `{}`",
token::get_ident(name),
- self.module_to_str(&*orig_module));
+ self.module_to_string(&*orig_module));
}
Some(module_) => {
self.current_module = module_;
item.id,
ItemRibKind),
|this| {
+ this.resolve_type_parameters(&generics.ty_params);
visit::walk_item(this, item, ());
});
}
methods.as_slice());
}
- ItemTrait(ref generics, _, ref traits, ref methods) => {
+ ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
// Create a new rib for the self type.
let self_type_rib = Rib::new(ItemRibKind);
- // plain insert (no renaming)
- let name = self.type_self_ident.name;
+ // plain insert (no renaming, types are not currently hygienic....)
+ let name = self.type_self_name;
self_type_rib.bindings.borrow_mut()
.insert(name, DlDef(DefSelfTy(item.id)));
self.type_ribs.borrow_mut().push(self_type_rib);
for trt in traits.iter() {
this.resolve_trait_reference(item.id, trt, TraitDerivation);
}
+ match unbound {
+ &Some(ast::TraitTyParamBound(ref tpb)) => {
+ this.resolve_trait_reference(item.id, tpb, TraitDerivation);
+ }
+ _ => {}
+ }
for method in (*methods).iter() {
// Create a new rib for the method-specific type
}
fn resolve_type_parameters(&mut self,
- type_parameters: &OwnedSlice<TyParam>) {
+ type_parameters: &OwnedSlice<TyParam>) {
for type_parameter in type_parameters.iter() {
for bound in type_parameter.bounds.iter() {
self.resolve_type_parameter_bound(type_parameter.id, bound);
}
+ match &type_parameter.unbound {
+ &Some(ref unbound) => self.resolve_type_parameter_bound(type_parameter.id, unbound),
+ &None => {}
+ }
match type_parameter.default {
Some(ref ty) => self.resolve_type(&**ty),
None => {}
}
fn resolve_trait_reference(&mut self,
- id: NodeId,
- trait_reference: &TraitRef,
- reference_type: TraitReferenceType) {
+ id: NodeId,
+ trait_reference: &TraitRef,
+ reference_type: TraitReferenceType) {
match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
None => {
- let path_str = self.path_idents_to_str(&trait_reference.path);
+ let path_str = self.path_idents_to_string(&trait_reference.path);
let usage_str = match reference_type {
TraitBoundingTypeParameter => "bound type parameter with",
TraitImplementation => "implement",
(def, _) => {
self.resolve_error(trait_reference.path.span,
format!("`{}` is not a trait",
- self.path_idents_to_str(
+ self.path_idents_to_string(
&trait_reference.path)));
// If it's a typedef, give a note
.identifier),
def);
debug!("(resolving struct) writing resolution for `{}` (id {})",
- this.path_idents_to_str(path),
+ this.path_idents_to_string(path),
path_id);
this.record_def(path_id, (def, lp));
}
fn resolve_method(&mut self,
rib_kind: RibKind,
method: &Method) {
- let method_generics = &method.generics;
+ let method_generics = ast_util::method_generics(method);
let type_parameters = HasTypeParameters(method_generics,
FnSpace,
method.id,
rib_kind);
- self.resolve_function(rib_kind, Some(method.decl), type_parameters, method.body);
+ self.resolve_function(rib_kind, Some(ast_util::method_fn_decl(method)),
+ type_parameters,
+ ast_util::method_body(method));
}
fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T {
fn check_trait_method(&self, method: &Method) {
// If there is a TraitRef in scope for an impl, then the method must be in the trait.
for &(did, ref trait_ref) in self.current_trait_ref.iter() {
- let method_name = method.ident.name;
+ let method_name = ast_util::method_ident(method).name;
if self.method_map.borrow().find(&(method_name, did)).is_none() {
- let path_str = self.path_idents_to_str(&trait_ref.path);
+ let path_str = self.path_idents_to_string(&trait_ref.path);
self.resolve_error(method.span,
format!("method `{}` is not a member of trait `{}`",
token::get_name(method_name),
// Write the result into the def map.
debug!("(resolving type) writing resolution for `{}` \
(id {})",
- self.path_idents_to_str(path),
+ self.path_idents_to_string(path),
path_id);
self.record_def(path_id, def);
}
None => {
let msg = format!("use of undeclared type name `{}`",
- self.path_idents_to_str(path));
+ self.path_idents_to_string(path));
self.resolve_error(ty.span, msg.as_slice());
}
}
PatStruct(ref path, _, _) => {
match self.resolve_path(pat_id, path, TypeNS, false) {
- Some((DefTy(class_id), lp))
- if self.structs.contains_key(&class_id) => {
- let class_def = DefStruct(class_id);
- self.record_def(pattern.id, (class_def, lp));
- }
- Some(definition @ (DefStruct(class_id), _)) => {
- assert!(self.structs.contains_key(&class_id));
- self.record_def(pattern.id, definition);
- }
- Some(definition @ (DefVariant(_, variant_id, _), _))
- if self.structs.contains_key(&variant_id) => {
+ Some(definition) => {
self.record_def(pattern.id, definition);
}
result => {
debug!("(resolving pattern) didn't find struct \
def: {:?}", result);
let msg = format!("`{}` does not name a structure",
- self.path_idents_to_str(path));
+ self.path_idents_to_string(path));
self.resolve_error(path.span, msg.as_slice());
}
}
Some((span, msg)) => (span, msg),
None => {
let msg = format!("Use of undeclared module `{}`",
- self.idents_to_str(
+ self.idents_to_string(
module_path_idents.as_slice()));
(path.span, msg)
}
Some((span, msg)) => (span, msg),
None => {
let msg = format!("Use of undeclared module `::{}`",
- self.idents_to_str(
+ self.idents_to_string(
module_path_idents.as_slice()));
(path.span, msg)
}
match get_module(self, path.span, ident_path.as_slice()) {
Some(module) => match module.children.borrow().find(&name) {
Some(binding) => {
- let p_str = self.path_idents_to_str(&path);
+ let p_str = self.path_idents_to_string(&path);
match binding.def_for_namespace(ValueNS) {
Some(DefStaticMethod(_, provenance, _)) => {
match provenance {
let method_map = self.method_map.borrow();
match self.current_trait_ref {
Some((did, ref trait_ref)) => {
- let path_str = self.path_idents_to_str(&trait_ref.path);
+ let path_str = self.path_idents_to_string(&trait_ref.path);
match method_map.find(&(name, did)) {
Some(&SelfStatic) => return StaticTraitMethod(path_str),
Some(def) => {
// Write the result into the def map.
debug!("(resolving expr) resolved `{}`",
- self.path_idents_to_str(path));
+ self.path_idents_to_string(path));
// First-class methods are not supported yet; error
// out here.
self.record_def(expr.id, def);
}
None => {
- let wrong_name = self.path_idents_to_str(path);
+ let wrong_name = self.path_idents_to_string(path);
// Be helpful if the name refers to a struct
// (The pattern matching def_tys where the id is in self.structs
// matches on regular structs while excluding tuple- and enum-like
}
_ => {
let mut method_scope = false;
- self.value_ribs.borrow().iter().rev().advance(|rib| {
+ self.value_ribs.borrow().iter().rev().all(|rib| {
let res = match *rib {
Rib { bindings: _, kind: MethodRibKind(_, _) } => true,
Rib { bindings: _, kind: ItemRibKind } => false,
false // Stop advancing
});
- if method_scope && token::get_name(self.self_ident.name).get()
- == wrong_name.as_slice() {
+ if method_scope && token::get_name(self.self_name).get()
+ == wrong_name.as_slice() {
self.resolve_error(
expr.span,
"`self` is not available \
}
ExprStruct(ref path, _, _) => {
- // Resolve the path to the structure it goes to.
+ // Resolve the path to the structure it goes to. We don't
+ // check to ensure that the path is actually a structure; that
+ // is checked later during typeck.
match self.resolve_path(expr.id, path, TypeNS, false) {
- Some((DefTy(class_id), lp)) | Some((DefStruct(class_id), lp))
- if self.structs.contains_key(&class_id) => {
- let class_def = DefStruct(class_id);
- self.record_def(expr.id, (class_def, lp));
- }
- Some(definition @ (DefVariant(_, class_id, _), _))
- if self.structs.contains_key(&class_id) => {
- self.record_def(expr.id, definition);
- }
+ Some(definition) => self.record_def(expr.id, definition),
result => {
debug!("(resolving expression) didn't find struct \
def: {:?}", result);
let msg = format!("`{}` does not name a structure",
- self.path_idents_to_str(path));
+ self.path_idents_to_string(path));
self.resolve_error(path.span, msg.as_slice());
}
}
//
/// A somewhat inefficient routine to obtain the name of a module.
- fn module_to_str(&self, module: &Module) -> String {
+ fn module_to_string(&self, module: &Module) -> String {
let mut idents = Vec::new();
fn collect_mod(idents: &mut Vec<ast::Ident>, module: &Module) {
collect_mod(idents, &*module.upgrade().unwrap());
}
BlockParentLink(ref module, _) => {
+ // danger, shouldn't be ident?
idents.push(special_idents::opaque);
collect_mod(idents, &*module.upgrade().unwrap());
}
if idents.len() == 0 {
return "???".to_string();
}
- self.idents_to_str(idents.move_iter().rev()
+ self.idents_to_string(idents.move_iter().rev()
.collect::<Vec<ast::Ident>>()
.as_slice())
}
#[allow(dead_code)] // useful for debugging
fn dump_module(&mut self, module_: Rc<Module>) {
- debug!("Dump of module `{}`:", self.module_to_str(&*module_));
+ debug!("Dump of module `{}`:", self.module_to_string(&*module_));
debug!("Children:");
self.populate_module_if_necessary(&module_);
use syntax::owned_slice::OwnedSlice;
use syntax::parse::token::special_idents;
use syntax::parse::token;
-use syntax::print::pprust::{lifetime_to_str};
+use syntax::print::pprust::{lifetime_to_string};
use syntax::visit;
use syntax::visit::Visitor;
use util::nodemap::NodeMap;
}
debug!("lifetime_ref={} id={} resolved to {:?}",
- lifetime_to_str(lifetime_ref),
+ lifetime_to_string(lifetime_ref),
lifetime_ref.id,
def);
self.named_region_map.insert(lifetime_ref.id, def);
use syntax::parse::token::{get_ident,keywords};
use syntax::visit;
use syntax::visit::Visitor;
-use syntax::print::pprust::{path_to_str,ty_to_str};
+use syntax::print::pprust::{path_to_string,ty_to_string};
use middle::save::span_utils::SpanUtils;
use middle::save::recorder::Recorder;
if spans.len() < path.segments.len() {
error!("Mis-calculated spans for path '{}'. \
Found {} spans, expected {}. Found spans:",
- path_to_str(path), spans.len(), path.segments.len());
+ path_to_string(path), spans.len(), path.segments.len());
for s in spans.iter() {
let loc = self.sess.codemap().lookup_char_pos(s.lo);
error!(" '{}' in {}, line {}",
let sub_path = ast::Path{span: *span, // span for the last segment
global: path.global,
segments: segs};
- let qualname = path_to_str(&sub_path);
+ let qualname = path_to_string(&sub_path);
result.push((*span, qualname));
segs = sub_path.segments;
}
self.collecting = false;
let span_utils = self.span;
for &(id, ref p, _, _) in self.collected_paths.iter() {
- let typ = ppaux::ty_to_str(&self.analysis.ty_cx,
+ let typ = ppaux::ty_to_string(&self.analysis.ty_cx,
*self.analysis.ty_cx.node_types.borrow().get(&(id as uint)));
// get the span only for the name of the variable (I hope the path is only ever a
// variable name, but who knows?)
span_utils.span_for_last_ident(p.span),
id,
qualname,
- path_to_str(p).as_slice(),
+ path_to_string(p).as_slice(),
typ.as_slice());
}
self.collected_paths.clear();
match item.node {
ast::ItemImpl(_, _, ty, _) => {
let mut result = String::from_str("<");
- result.push_str(ty_to_str(&*ty).as_slice());
+ result.push_str(ty_to_string(&*ty).as_slice());
match ty::trait_of_method(&self.analysis.ty_cx,
ast_util::local_def(method.id)) {
},
};
- qualname.push_str(get_ident(method.ident).get());
+ qualname.push_str(get_ident(ast_util::method_ident(&*method)).get());
let qualname = qualname.as_slice();
// record the decl for this def (if it has one)
decl_id,
scope_id);
- self.process_formals(&method.decl.inputs, qualname, e);
+ let m_decl = ast_util::method_fn_decl(&*method);
+ self.process_formals(&m_decl.inputs, qualname, e);
// walk arg and return types
- for arg in method.decl.inputs.iter() {
+ for arg in m_decl.inputs.iter() {
self.visit_ty(&*arg.ty, e);
}
- self.visit_ty(&*method.decl.output, e);
+ self.visit_ty(m_decl.output, e);
// walk the fn body
- self.visit_block(&*method.body, DxrVisitorEnv::new_nested(method.id));
+ self.visit_block(ast_util::method_body(&*method), DxrVisitorEnv::new_nested(method.id));
- self.process_generic_params(&method.generics,
+ self.process_generic_params(ast_util::method_generics(&*method),
method.span,
qualname,
method.id,
ast::NamedField(ident, _) => {
let name = get_ident(ident);
let qualname = format!("{}::{}", qualname, name);
- let typ = ppaux::ty_to_str(&self.analysis.ty_cx,
+ let typ = ppaux::ty_to_string(&self.analysis.ty_cx,
*self.analysis.ty_cx.node_types.borrow().get(&(field.node.id as uint)));
match self.span.sub_span_before_token(field.span, token::COLON) {
Some(sub_span) => self.fmt.field_str(field.span,
decl: ast::P<ast::FnDecl>,
ty_params: &ast::Generics,
body: ast::P<ast::Block>) {
- let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+ let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Fn);
self.fmt.fn_str(item.span,
mt: ast::Mutability,
expr: &ast::Expr)
{
- let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+ let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
// If the variable is immutable, save the initialising expression.
let value = match mt {
get_ident(item.ident).get(),
qualname.as_slice(),
value.as_slice(),
- ty_to_str(&*typ).as_slice(),
+ ty_to_string(&*typ).as_slice(),
e.cur_scope);
// walk type and init value
e: DxrVisitorEnv,
def: &ast::StructDef,
ty_params: &ast::Generics) {
- let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+ let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
let ctor_id = match def.ctor_id {
Some(node_id) => node_id,
e: DxrVisitorEnv,
enum_definition: &ast::EnumDef,
ty_params: &ast::Generics) {
- let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+ let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
match self.span.sub_span_after_keyword(item.span, keywords::Enum) {
Some(sub_span) => self.fmt.enum_str(item.span,
Some(sub_span),
generics: &ast::Generics,
trait_refs: &Vec<ast::TraitRef>,
methods: &Vec<ast::TraitMethod>) {
- let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+ let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Trait);
self.fmt.trait_str(item.span,
item: &ast::Item, // The module in question, represented as an item.
e: DxrVisitorEnv,
m: &ast::Mod) {
- let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
+ let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
let cm = self.sess.codemap();
let filename = cm.span_to_filename(m.inner);
self.process_trait(item, e, generics, trait_refs, methods),
ast::ItemMod(ref m) => self.process_mod(item, e, m),
ast::ItemTy(ty, ref ty_params) => {
- let qualname = self.analysis.ty_cx.map.path_to_str(item.id);
- let value = ty_to_str(&*ty);
+ let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
+ let value = ty_to_string(&*ty);
let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Type);
self.fmt.typedef_str(item.span,
sub_span,
return
}
- let id = String::from_str("$").append(ex.id.to_str().as_slice());
+ let id = String::from_str("$").append(ex.id.to_string().as_slice());
self.process_formals(&decl.inputs, id.as_slice(), e);
// walk arg and return types
def::DefBinding(id, _) => self.fmt.variable_str(p.span,
sub_span,
id,
- path_to_str(p).as_slice(),
+ path_to_string(p).as_slice(),
value.as_slice(),
""),
def::DefVariant(_,id,_) => self.fmt.ref_str(ref_kind,
for &(id, ref p, ref immut, _) in self.collected_paths.iter() {
let value = if *immut { value.to_owned() } else { "<mutable>".to_owned() };
let types = self.analysis.ty_cx.node_types.borrow();
- let typ = ppaux::ty_to_str(&self.analysis.ty_cx, *types.get(&(id as uint)));
+ let typ = ppaux::ty_to_string(&self.analysis.ty_cx, *types.get(&(id as uint)));
// Get the span only for the name of the variable (I hope the path
// is only ever a variable name, but who knows?).
let sub_span = self.span.span_for_last_ident(p.span);
self.fmt.variable_str(p.span,
sub_span,
id,
- path_to_str(p).as_slice(),
+ path_to_string(p).as_slice(),
value.as_slice(),
typ.as_slice());
}
return;
}
- let (cratename, crateid) = match attr::find_crateid(krate.attrs.as_slice()) {
- Some(crateid) => (crateid.name.clone(), crateid.to_str()),
+ let cratename = match attr::find_crate_name(krate.attrs.as_slice()) {
+ Some(name) => name.get().to_string(),
None => {
info!("Could not find crate name, using 'unknown_crate'");
- (String::from_str("unknown_crate"),"unknown_crate".to_owned())
+ String::from_str("unknown_crate")
},
};
- info!("Dumping crate {} ({})", cratename, crateid);
+ info!("Dumping crate {}", cratename);
// find a path to dump our data to
let mut root_path = match os::getenv("DXR_RUST_TEMP_FOLDER") {
// the local case they can be overridden in one block and there is no nice way
// to refer to such a scope in english, so we just hack it by appending the
// variable def's node id
- let qualname = String::from_str(name).append("$").append(id.to_str().as_slice());
+ let qualname = String::from_str(name).append("$").append(id.to_string().as_slice());
self.check_and_record(Variable,
span,
sub_span,
use util::nodemap::{NodeMap, DefIdMap};
use syntax::codemap::Span;
use syntax::{attr, visit};
+use syntax::ast;
use syntax::ast::{Attribute, Block, Crate, DefId, FnDecl, NodeId, Variant};
use syntax::ast::{Item, Required, Provided, TraitMethod, TypeMethod, Method};
-use syntax::ast::{Generics, StructDef, Ident};
+use syntax::ast::{Generics, StructDef, StructField, Ident};
use syntax::ast_util::is_local;
use syntax::attr::Stability;
use syntax::visit::{FnKind, FkMethod, Visitor};
s.ctor_id.map(|id| self.annotate(id, &[], parent.clone()));
visit::walk_struct_def(self, s, parent)
}
+
+ fn visit_struct_field(&mut self, s: &StructField, parent: Option<Stability>) {
+ let stab = self.annotate(s.node.id, s.node.attrs.as_slice(), parent);
+ visit::walk_struct_field(self, s, stab)
+ }
}
impl Index {
extern_cache: DefIdMap::new()
}
};
- visit::walk_crate(&mut annotator, krate,
- attr::find_stability(krate.attrs.as_slice()));
+ let stab = annotator.annotate(ast::CRATE_NODE_ID, krate.attrs.as_slice(), None);
+ visit::walk_crate(&mut annotator, krate, stab);
annotator.index
}
}
use middle::ty_fold::{TypeFoldable, TypeFolder};
use util::ppaux::Repr;
-use std::iter::Chain;
use std::mem;
use std::raw;
use std::slice::{Items, MutItems};
}
pub fn with_method_from(self, substs: &Substs) -> Substs {
- self.with_method((*substs.types.get_vec(FnSpace)).clone(),
- (*substs.regions().get_vec(FnSpace)).clone())
+ self.with_method(Vec::from_slice(substs.types.get_slice(FnSpace)),
+ Vec::from_slice(substs.regions().get_slice(FnSpace)))
}
pub fn with_method(self,
*/
#[deriving(PartialEq, Eq, Clone, Hash, Encodable, Decodable)]
pub struct VecPerParamSpace<T> {
- vecs: (Vec<T>, Vec<T>, Vec<T>)
+ // This was originally represented as a tuple with one Vec<T> for
+ // each variant of ParamSpace, and that remains the abstraction
+ // that it provides to its clients.
+ //
+ // Here is how the representation corresponds to the abstraction
+ // i.e. the "abstraction function" AF:
+ //
+ // AF(self) = (self.content.slice_to(self.type_limit),
+ // self.content.slice(self.type_limit, self.self_limit),
+ // self.content.slice_from(self.self_limit))
+ type_limit: uint,
+ self_limit: uint,
+ content: Vec<T>,
+}
+
+impl<T:Clone> VecPerParamSpace<T> {
+ pub fn push_all(&mut self, space: ParamSpace, values: &[T]) {
+ // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
+ for t in values.iter() {
+ self.push(space, t.clone());
+ }
+ }
}
impl<T> VecPerParamSpace<T> {
+ fn limits(&self, space: ParamSpace) -> (uint, uint) {
+ match space {
+ TypeSpace => (0, self.type_limit),
+ SelfSpace => (self.type_limit, self.self_limit),
+ FnSpace => (self.self_limit, self.content.len()),
+ }
+ }
+
pub fn empty() -> VecPerParamSpace<T> {
VecPerParamSpace {
- vecs: (Vec::new(), Vec::new(), Vec::new())
+ type_limit: 0,
+ self_limit: 0,
+ content: Vec::new()
}
}
}
pub fn new(t: Vec<T>, s: Vec<T>, f: Vec<T>) -> VecPerParamSpace<T> {
+ let type_limit = t.len();
+ let self_limit = t.len() + s.len();
+ let mut content = t;
+ content.push_all_move(s);
+ content.push_all_move(f);
VecPerParamSpace {
- vecs: (t, s, f)
+ type_limit: type_limit,
+ self_limit: self_limit,
+ content: content,
}
}
result
}
+ /// Appends `value` to the vector associated with `space`.
+ ///
+ /// Unlike the `push` method in `Vec`, this should not be assumed
+ /// to be a cheap operation (even when amortized over many calls).
pub fn push(&mut self, space: ParamSpace, value: T) {
- self.get_mut_vec(space).push(value);
+ let (_, limit) = self.limits(space);
+ match space {
+ TypeSpace => { self.type_limit += 1; self.self_limit += 1; }
+ SelfSpace => { self.self_limit += 1; }
+ FnSpace => {}
+ }
+ self.content.insert(limit, value);
+ }
+
+ pub fn pop(&mut self, space: ParamSpace) -> Option<T> {
+ let (start, limit) = self.limits(space);
+ if start == limit {
+ None
+ } else {
+ match space {
+ TypeSpace => { self.type_limit -= 1; self.self_limit -= 1; }
+ SelfSpace => { self.self_limit -= 1; }
+ FnSpace => {}
+ }
+ self.content.remove(limit - 1)
+ }
+ }
+
+ pub fn truncate(&mut self, space: ParamSpace, len: uint) {
+ // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
+ while self.len(space) > len {
+ self.pop(space);
+ }
+ }
+
+ pub fn replace(&mut self, space: ParamSpace, elems: Vec<T>) {
+ // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
+ self.truncate(space, 0);
+ for t in elems.move_iter() {
+ self.push(space, t);
+ }
}
pub fn get_self<'a>(&'a self) -> Option<&'a T> {
- let v = self.get_vec(SelfSpace);
+ let v = self.get_slice(SelfSpace);
assert!(v.len() <= 1);
- if v.len() == 0 { None } else { Some(v.get(0)) }
+ if v.len() == 0 { None } else { Some(&v[0]) }
}
pub fn len(&self, space: ParamSpace) -> uint {
- self.get_vec(space).len()
+ self.get_slice(space).len()
+ }
+
+ pub fn is_empty_in(&self, space: ParamSpace) -> bool {
+ self.len(space) == 0
}
- pub fn get_vec<'a>(&'a self, space: ParamSpace) -> &'a Vec<T> {
- self.vecs.get(space as uint).unwrap()
+ pub fn get_slice<'a>(&'a self, space: ParamSpace) -> &'a [T] {
+ let (start, limit) = self.limits(space);
+ self.content.slice(start, limit)
}
- pub fn get_mut_vec<'a>(&'a mut self, space: ParamSpace) -> &'a mut Vec<T> {
- self.vecs.get_mut(space as uint).unwrap()
+ fn get_mut_slice<'a>(&'a mut self, space: ParamSpace) -> &'a mut [T] {
+ let (start, limit) = self.limits(space);
+ self.content.mut_slice(start, limit)
}
pub fn opt_get<'a>(&'a self,
space: ParamSpace,
index: uint)
-> Option<&'a T> {
- let v = self.get_vec(space);
- if index < v.len() { Some(v.get(index)) } else { None }
+ let v = self.get_slice(space);
+ if index < v.len() { Some(&v[index]) } else { None }
}
pub fn get<'a>(&'a self, space: ParamSpace, index: uint) -> &'a T {
- self.get_vec(space).get(index)
+ &self.get_slice(space)[index]
}
pub fn get_mut<'a>(&'a mut self,
space: ParamSpace,
index: uint) -> &'a mut T {
- self.get_mut_vec(space).get_mut(index)
+ &mut self.get_mut_slice(space)[index]
}
- pub fn iter<'a>(&'a self) -> Chain<Items<'a,T>,
- Chain<Items<'a,T>,
- Items<'a,T>>> {
- let (ref r, ref s, ref f) = self.vecs;
- r.iter().chain(s.iter().chain(f.iter()))
+ pub fn iter<'a>(&'a self) -> Items<'a,T> {
+ self.content.iter()
}
- pub fn all_vecs(&self, pred: |&Vec<T>| -> bool) -> bool {
- self.vecs.iter().all(pred)
+ pub fn all_vecs(&self, pred: |&[T]| -> bool) -> bool {
+ let spaces = [TypeSpace, SelfSpace, FnSpace];
+ spaces.iter().all(|&space| { pred(self.get_slice(space)) })
}
pub fn all(&self, pred: |&T| -> bool) -> bool {
}
pub fn map<U>(&self, pred: |&T| -> U) -> VecPerParamSpace<U> {
- VecPerParamSpace::new(self.vecs.ref0().iter().map(|p| pred(p)).collect(),
- self.vecs.ref1().iter().map(|p| pred(p)).collect(),
- self.vecs.ref2().iter().map(|p| pred(p)).collect())
+ // FIXME (#15418): this could avoid allocating the intermediate
+ // Vec's, but note that the values of type_limit and self_limit
+ // also need to be kept in sync during construction.
+ VecPerParamSpace::new(
+ self.get_slice(TypeSpace).iter().map(|p| pred(p)).collect(),
+ self.get_slice(SelfSpace).iter().map(|p| pred(p)).collect(),
+ self.get_slice(FnSpace).iter().map(|p| pred(p)).collect())
}
pub fn map_rev<U>(&self, pred: |&T| -> U) -> VecPerParamSpace<U> {
* can be run to a fixed point
*/
- let mut fns: Vec<U> = self.vecs.ref2().iter().rev().map(|p| pred(p)).collect();
+ let mut fns: Vec<U> = self.get_slice(FnSpace).iter().rev().map(|p| pred(p)).collect();
// NB: Calling foo.rev().map().rev() causes the calls to map
// to occur in the wrong order. This was somewhat surprising
// to me, though it makes total sense.
fns.reverse();
- let mut selfs: Vec<U> = self.vecs.ref1().iter().rev().map(|p| pred(p)).collect();
+ let mut selfs: Vec<U> = self.get_slice(SelfSpace).iter().rev().map(|p| pred(p)).collect();
selfs.reverse();
- let mut tys: Vec<U> = self.vecs.ref0().iter().rev().map(|p| pred(p)).collect();
+ let mut tys: Vec<U> = self.get_slice(TypeSpace).iter().rev().map(|p| pred(p)).collect();
tys.reverse();
VecPerParamSpace::new(tys, selfs, fns)
}
pub fn split(self) -> (Vec<T>, Vec<T>, Vec<T>) {
- self.vecs
+ // FIXME (#15418): this does two traversals when in principle
+ // one would suffice. i.e. change to use `move_iter`.
+ let VecPerParamSpace { type_limit, self_limit, content } = self;
+ let mut i = 0;
+ let (prefix, fn_vec) = content.partition(|_| {
+ let on_left = i < self_limit;
+ i += 1;
+ on_left
+ });
+
+ let mut i = 0;
+ let (type_vec, self_vec) = prefix.partition(|_| {
+ let on_left = i < type_limit;
+ i += 1;
+ on_left
+ });
+
+ (type_vec, self_vec, fn_vec)
}
pub fn with_vec(mut self, space: ParamSpace, vec: Vec<T>)
-> VecPerParamSpace<T>
{
- assert!(self.get_vec(space).is_empty());
- *self.get_mut_vec(space) = vec;
+ assert!(self.is_empty_in(space));
+ self.replace(space, vec);
self
}
}
use back::abi;
use driver::config::FullDebugInfo;
-use lib::llvm::{llvm, ValueRef, BasicBlockRef};
+use llvm;
+use llvm::{ValueRef, BasicBlockRef};
use middle::const_eval;
use middle::def;
use middle::check_match;
use middle::trans::debuginfo;
use middle::ty;
use util::common::indenter;
-use util::ppaux::{Repr, vec_map_to_str};
+use util::ppaux::{Repr, vec_map_to_string};
use std;
use std::collections::HashMap;
bcx.to_str(),
m.repr(bcx.tcx()),
col,
- bcx.val_to_str(val));
+ bcx.val_to_string(val));
let _indenter = indenter();
m.iter().map(|br| {
- match br.pats.get(col).node {
- ast::PatIdent(_, ref path1, Some(inner)) => {
- let pats = Vec::from_slice(br.pats.slice(0u, col))
- .append((vec!(inner))
- .append(br.pats.slice(col + 1u, br.pats.len())).as_slice());
-
- let mut bound_ptrs = br.bound_ptrs.clone();
- bound_ptrs.push((path1.node, val));
- Match {
- pats: pats,
- data: &*br.data,
- bound_ptrs: bound_ptrs
- }
- }
- _ => Match {
- pats: br.pats.clone(),
- data: &*br.data,
- bound_ptrs: br.bound_ptrs.clone()
+ let mut bound_ptrs = br.bound_ptrs.clone();
+ let mut pat = *br.pats.get(col);
+ loop {
+ pat = match pat.node {
+ ast::PatIdent(_, ref path, Some(inner)) => {
+ bound_ptrs.push((path.node, val));
+ inner.clone()
+ },
+ _ => break
}
}
+
+ let mut pats = br.pats.clone();
+ *pats.get_mut(col) = pat;
+ Match {
+ pats: pats,
+ data: &*br.data,
+ bound_ptrs: bound_ptrs
+ }
}).collect()
}
bcx.to_str(),
m.repr(bcx.tcx()),
col,
- bcx.val_to_str(val));
+ bcx.val_to_string(val));
let _indenter = indenter();
m.iter().filter_map(|br| {
bcx.to_str(),
m.repr(bcx.tcx()),
col,
- bcx.val_to_str(val));
+ bcx.val_to_string(val));
let _indenter = indenter();
// Collect all of the matches that can match against anything.
m.repr(bcx.tcx()),
*opt,
col,
- bcx.val_to_str(val));
+ bcx.val_to_string(val));
let _indenter = indenter();
let ctor = match opt {
// matches should fit that sort of pattern or NONE (however, some of the
// matches may be wildcards like _ or identifiers).
macro_rules! any_pat (
- ($m:expr, $pattern:pat) => (
+ ($m:expr, $col:expr, $pattern:pat) => (
($m).iter().any(|br| {
- match br.pats.get(col).node {
+ match br.pats.get($col).node {
$pattern => true,
_ => false
}
)
fn any_uniq_pat(m: &[Match], col: uint) -> bool {
- any_pat!(m, ast::PatBox(_))
+ any_pat!(m, col, ast::PatBox(_))
}
fn any_region_pat(m: &[Match], col: uint) -> bool {
- any_pat!(m, ast::PatRegion(_))
+ any_pat!(m, col, ast::PatRegion(_))
}
fn any_irrefutable_adt_pat(bcx: &Block, m: &[Match], col: uint) -> bool {
let pat = *br.pats.get(col);
match pat.node {
ast::PatTup(_) => true,
- ast::PatEnum(..) | ast::PatIdent(_, _, None) | ast::PatStruct(..) =>
+ ast::PatStruct(..) => {
+ match bcx.tcx().def_map.borrow().find(&pat.id) {
+ Some(&def::DefVariant(..)) => false,
+ _ => true,
+ }
+ }
+ ast::PatEnum(..) | ast::PatIdent(_, _, None) => {
match bcx.tcx().def_map.borrow().find(&pat.id) {
Some(&def::DefFn(..)) |
Some(&def::DefStruct(..)) => true,
_ => false
- },
+ }
+ }
_ => false
}
})
let did = langcall(cx,
None,
format!("comparison of `{}`",
- cx.ty_to_str(rhs_t)).as_slice(),
+ cx.ty_to_string(rhs_t)).as_slice(),
StrEqFnLangItem);
callee::trans_lang_call(cx, did, [lhs, rhs], None)
}
}
}
-fn insert_lllocals<'a>(mut bcx: &'a Block<'a>,
- bindings_map: &BindingsMap)
+fn insert_lllocals<'a>(mut bcx: &'a Block<'a>, bindings_map: &BindingsMap,
+ cs: Option<cleanup::ScopeId>)
-> &'a Block<'a> {
/*!
* For each binding in `data.bindings_map`, adds an appropriate entry into
};
let datum = Datum::new(llval, binding_info.ty, Lvalue);
+ match cs {
+ Some(cs) => bcx.fcx.schedule_drop_and_zero_mem(cs, llval, binding_info.ty),
+ _ => {}
+ }
debug!("binding {:?} to {}",
binding_info.id,
- bcx.val_to_str(llval));
+ bcx.val_to_string(llval));
bcx.fcx.lllocals.borrow_mut().insert(binding_info.id, datum);
if bcx.sess().opts.debuginfo == FullDebugInfo {
-> &'b Block<'b> {
debug!("compile_guard(bcx={}, guard_expr={}, m={}, vals={})",
bcx.to_str(),
- bcx.expr_to_str(guard_expr),
+ bcx.expr_to_string(guard_expr),
m.repr(bcx.tcx()),
- vec_map_to_str(vals, |v| bcx.val_to_str(*v)));
+ vec_map_to_string(vals, |v| bcx.val_to_string(*v)));
let _indenter = indenter();
- let mut bcx = insert_lllocals(bcx, &data.bindings_map);
+ let mut bcx = insert_lllocals(bcx, &data.bindings_map, None);
let val = unpack_datum!(bcx, expr::trans(bcx, guard_expr));
let val = val.to_llbool(bcx);
debug!("compile_submatch(bcx={}, m={}, vals={})",
bcx.to_str(),
m.repr(bcx.tcx()),
- vec_map_to_str(vals, |v| bcx.val_to_str(*v)));
+ vec_map_to_string(vals, |v| bcx.val_to_string(*v)));
let _indenter = indenter();
let _icx = push_ctxt("match::compile_submatch");
let mut bcx = bcx;
debug!("options={:?}", opts);
let mut kind = no_branch;
let mut test_val = val;
- debug!("test_val={}", bcx.val_to_str(test_val));
+ debug!("test_val={}", bcx.val_to_string(test_val));
if opts.len() > 0u {
match *opts.get(0) {
var(_, ref repr, _) => {
for arm_data in arm_datas.iter() {
let mut bcx = arm_data.bodycx;
- // insert bindings into the lllocals map
- bcx = insert_lllocals(bcx, &arm_data.bindings_map);
+ // insert bindings into the lllocals map and add cleanups
+ let cs = fcx.push_custom_cleanup_scope();
+ bcx = insert_lllocals(bcx, &arm_data.bindings_map, Some(cleanup::CustomScope(cs)));
bcx = expr::trans_into(bcx, &*arm_data.arm.body, dest);
+ bcx = fcx.pop_and_trans_custom_cleanup_scope(bcx, cs);
arm_cxs.push(bcx);
}
use libc::c_ulonglong;
use std::rc::Rc;
-use lib::llvm::{ValueRef, True, IntEQ, IntNE};
+use llvm::{ValueRef, True, IntEQ, IntNE};
use middle::subst;
use middle::subst::Subst;
use middle::trans::_match;
use syntax::ast;
use syntax::attr;
use syntax::attr::IntType;
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
type Hint = attr::ReprAttr;
StructWrappedNullablePointer {
pub nonnull: Struct,
pub nndiscr: Disr,
- pub ptrfield: uint,
+ pub ptrfield: PointerField,
pub nullfields: Vec<ty::t>,
}
}
/// Decides how to represent a given type.
pub fn represent_type(cx: &CrateContext, t: ty::t) -> Rc<Repr> {
- debug!("Representing: {}", ty_to_str(cx.tcx(), t));
+ debug!("Representing: {}", ty_to_string(cx.tcx(), t));
match cx.adt_reprs.borrow().find(&t) {
Some(repr) => return repr.clone(),
None => {}
let mut discr = 0;
while discr < 2 {
if cases.get(1 - discr).is_zerolen(cx) {
+ let st = mk_struct(cx, cases.get(discr).tys.as_slice(), false);
match cases.get(discr).find_ptr() {
+ Some(ThinPointer(_)) if st.fields.len() == 1 => {
+ return RawNullablePointer {
+ nndiscr: discr as Disr,
+ nnty: *st.fields.get(0),
+ nullfields: cases.get(1 - discr).tys.clone()
+ };
+ }
Some(ptrfield) => {
- let st = mk_struct(cx, cases.get(discr).tys.as_slice(),
- false);
-
- return if st.fields.len() == 1 {
- RawNullablePointer {
- nndiscr: discr as Disr,
- nnty: *st.fields.get(0),
- nullfields: cases.get(1 - discr).tys.clone()
- }
- } else {
- StructWrappedNullablePointer {
- nndiscr: discr as Disr,
- nonnull: st,
- ptrfield: ptrfield,
- nullfields: cases.get(1 - discr).tys.clone()
- }
+ return StructWrappedNullablePointer {
+ nndiscr: discr as Disr,
+ nonnull: st,
+ ptrfield: ptrfield,
+ nullfields: cases.get(1 - discr).tys.clone()
};
}
None => { }
}
// this should probably all be in ty
-struct Case { discr: Disr, tys: Vec<ty::t> }
+struct Case {
+ discr: Disr,
+ tys: Vec<ty::t>
+}
+
+
+#[deriving(Show)]
+pub enum PointerField {
+ ThinPointer(uint),
+ FatPointer(uint, uint)
+}
+
impl Case {
fn is_zerolen(&self, cx: &CrateContext) -> bool {
mk_struct(cx, self.tys.as_slice(), false).size == 0
}
- fn find_ptr(&self) -> Option<uint> {
- self.tys.iter().position(|&ty| {
+ fn find_ptr(&self) -> Option<PointerField> {
+ use back::abi::{fn_field_code, slice_elt_base, trt_field_box};
+
+ for (i, &ty) in self.tys.iter().enumerate() {
match ty::get(ty).sty {
- ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
- ty::ty_vec(_, None) | ty::ty_str| ty::ty_trait(..) => false,
- _ => true,
+ // &T/&mut T could either be a thin or fat pointer depending on T
+ ty::ty_rptr(_, ty::mt { ty, .. }) => match ty::get(ty).sty {
+ // &[T] and &str are a pointer and length pair
+ ty::ty_vec(_, None) | ty::ty_str => return Some(FatPointer(i, slice_elt_base)),
+
+ // &Trait/&mut Trait are a pair of pointers: the actual object and a vtable
+ ty::ty_trait(..) => return Some(FatPointer(i, trt_field_box)),
+
+ // Any other &T/&mut T is just a pointer
+ _ => return Some(ThinPointer(i))
+ },
+
+ // Box<T> could either be a thin or fat pointer depending on T
+ ty::ty_uniq(t) => match ty::get(t).sty {
+ // Box<[T]>/Box<str> might be FatPointer in a post DST world
+ ty::ty_vec(_, None) | ty::ty_str => continue,
+
+ // Box<Trait> is a pair of pointers: the actual object and a vtable
+ ty::ty_trait(..) => return Some(FatPointer(i, trt_field_box)),
+
+ // Any other Box<T> is just a pointer
+ _ => return Some(ThinPointer(i))
},
- ty::ty_box(..) | ty::ty_bare_fn(..) => true,
- // Is that everything? Would closures or slices qualify?
- _ => false
+
+ // Gc<T> is just a pointer
+ ty::ty_box(..) => return Some(ThinPointer(i)),
+
+ // Functions are just pointers
+ ty::ty_bare_fn(..) => return Some(ThinPointer(i)),
+
+ // Closures are a pair of pointers: the code and environment
+ ty::ty_closure(..) => return Some(FatPointer(i, fn_field_code)),
+
+ // Anything else is not a pointer
+ _ => continue
+
}
- })
+ }
+
+ None
}
}
val = ICmp(bcx, cmp, Load(bcx, scrutinee), C_null(llptrty));
signed = false;
}
- StructWrappedNullablePointer { nonnull: ref nonnull, nndiscr, ptrfield, .. } => {
- val = struct_wrapped_nullable_bitdiscr(bcx, nonnull, nndiscr, ptrfield, scrutinee);
+ StructWrappedNullablePointer { nndiscr, ptrfield, .. } => {
+ val = struct_wrapped_nullable_bitdiscr(bcx, nndiscr, ptrfield, scrutinee);
signed = false;
}
}
}
}
-fn struct_wrapped_nullable_bitdiscr(bcx: &Block, nonnull: &Struct, nndiscr: Disr, ptrfield: uint,
+fn struct_wrapped_nullable_bitdiscr(bcx: &Block, nndiscr: Disr, ptrfield: PointerField,
scrutinee: ValueRef) -> ValueRef {
- let llptr = Load(bcx, GEPi(bcx, scrutinee, [0, ptrfield]));
+ let llptrptr = match ptrfield {
+ ThinPointer(field) => GEPi(bcx, scrutinee, [0, field]),
+ FatPointer(field, pair) => GEPi(bcx, scrutinee, [0, field, pair])
+ };
+ let llptr = Load(bcx, llptrptr);
let cmp = if nndiscr == 0 { IntEQ } else { IntNE };
- let llptrty = type_of::type_of(bcx.ccx(), *nonnull.fields.get(ptrfield));
- ICmp(bcx, cmp, llptr, C_null(llptrty))
+ ICmp(bcx, cmp, llptr, C_null(val_ty(llptr)))
}
/// Helper for cases where the discriminant is simply loaded.
RawNullablePointer { .. } |
StructWrappedNullablePointer { .. } => {
assert!(discr == 0 || discr == 1);
- _match::single_result(Result::new(bcx, C_i1(bcx.ccx(), discr != 0)))
+ _match::single_result(Result::new(bcx, C_bool(bcx.ccx(), discr != 0)))
}
}
}
}
Univariant(ref st, true) => {
assert_eq!(discr, 0);
- Store(bcx, C_bool(bcx.ccx(), true),
+ Store(bcx, C_u8(bcx.ccx(), 1),
GEPi(bcx, val, [0, st.fields.len() - 1]))
}
Univariant(..) => {
}
StructWrappedNullablePointer { nonnull: ref nonnull, nndiscr, ptrfield, .. } => {
if discr != nndiscr {
- let llptrptr = GEPi(bcx, val, [0, ptrfield]);
- let llptrty = type_of::type_of(bcx.ccx(),
- *nonnull.fields.get(ptrfield));
+ let (llptrptr, llptrty) = match ptrfield {
+ ThinPointer(field) =>
+ (GEPi(bcx, val, [0, field]),
+ type_of::type_of(bcx.ccx(), *nonnull.fields.get(field))),
+ FatPointer(field, pair) => {
+ let v = GEPi(bcx, val, [0, field, pair]);
+ (v, val_ty(v).element_type())
+ }
+ };
Store(bcx, C_null(llptrty), llptrptr)
}
}
}
}
StructWrappedNullablePointer { nndiscr, ptrfield, .. } => {
- if is_null(const_struct_field(ccx, val, ptrfield)) {
+ let (idx, sub_idx) = match ptrfield {
+ ThinPointer(field) => (field, None),
+ FatPointer(field, pair) => (field, Some(pair))
+ };
+ if is_null(const_struct_field(ccx, val, idx, sub_idx)) {
/* subtraction as uint is ok because nndiscr is either 0 or 1 */
(1 - nndiscr) as Disr
} else {
_discr: Disr, ix: uint) -> ValueRef {
match *r {
CEnum(..) => ccx.sess().bug("element access in C-like enum const"),
- Univariant(..) => const_struct_field(ccx, val, ix),
- General(..) => const_struct_field(ccx, val, ix + 1),
+ Univariant(..) => const_struct_field(ccx, val, ix, None),
+ General(..) => const_struct_field(ccx, val, ix + 1, None),
RawNullablePointer { .. } => {
assert_eq!(ix, 0);
val
}
- StructWrappedNullablePointer{ .. } => const_struct_field(ccx, val, ix)
+ StructWrappedNullablePointer{ .. } => const_struct_field(ccx, val, ix, None)
}
}
/// Extract field of struct-like const, skipping our alignment padding.
-fn const_struct_field(ccx: &CrateContext, val: ValueRef, ix: uint)
+fn const_struct_field(ccx: &CrateContext, val: ValueRef, ix: uint, sub_idx: Option<uint>)
-> ValueRef {
// Get the ix-th non-undef element of the struct.
let mut real_ix = 0; // actual position in the struct
let mut field;
loop {
loop {
- field = const_get_elt(ccx, val, [real_ix]);
+ field = match sub_idx {
+ Some(si) => const_get_elt(ccx, val, [real_ix, si as u32]),
+ None => const_get_elt(ccx, val, [real_ix])
+ };
if !is_undef(field) {
break;
}
# Translation of inline assembly.
*/
-use lib;
+use llvm;
use middle::trans::build::*;
use middle::trans::callee;
use middle::trans::common::*;
};
let dialect = match ia.dialect {
- ast::AsmAtt => lib::llvm::AD_ATT,
- ast::AsmIntel => lib::llvm::AD_Intel
+ ast::AsmAtt => llvm::AD_ATT,
+ ast::AsmIntel => llvm::AD_Intel
};
let r = ia.asm.get().with_c_str(|a| {
use driver::config;
use driver::config::{NoDebugInfo, FullDebugInfo};
use driver::session::Session;
-use driver::driver::OutputFilenames;
use driver::driver::{CrateAnalysis, CrateTranslation};
-use lib::llvm::{ModuleRef, ValueRef, BasicBlockRef};
-use lib::llvm::{llvm, Vector};
-use lib;
+use llvm;
+use llvm::{ModuleRef, ValueRef, BasicBlockRef};
+use llvm::{Vector};
use metadata::{csearch, encoder, loader};
use lint;
use middle::astencode;
use middle::ty;
use middle::typeck;
use util::common::indenter;
-use util::ppaux::{Repr, ty_to_str};
+use util::ppaux::{Repr, ty_to_string};
use util::sha2::Sha256;
use util::nodemap::NodeMap;
}
// only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
-fn decl_fn(ccx: &CrateContext, name: &str, cc: lib::llvm::CallConv,
+fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
ty: Type, output: ty::t) -> ValueRef {
let llfn: ValueRef = name.with_c_str(|buf| {
ty::ty_bot => {
unsafe {
llvm::LLVMAddFunctionAttribute(llfn,
- lib::llvm::FunctionIndex as c_uint,
- lib::llvm::NoReturnAttribute as uint64_t)
+ llvm::FunctionIndex as c_uint,
+ llvm::NoReturnAttribute as uint64_t)
}
}
_ => {}
}
- lib::llvm::SetFunctionCallConv(llfn, cc);
+ llvm::SetFunctionCallConv(llfn, cc);
// Function addresses in Rust are never significant, allowing functions to be merged.
- lib::llvm::SetUnnamedAddr(llfn, true);
+ llvm::SetUnnamedAddr(llfn, true);
if ccx.is_split_stack_supported() {
set_split_stack(llfn);
name: &str,
ty: Type,
output: ty::t) -> ValueRef {
- decl_fn(ccx, name, lib::llvm::CCallConv, ty, output)
+ decl_fn(ccx, name, llvm::CCallConv, ty, output)
}
// only use this for foreign function ABIs and glue, use `get_extern_rust_fn` for Rust functions
pub fn get_extern_fn(ccx: &CrateContext,
externs: &mut ExternMap,
name: &str,
- cc: lib::llvm::CallConv,
+ cc: llvm::CallConv,
ty: Type,
output: ty::t)
-> ValueRef {
};
let llfty = type_of_rust_fn(ccx, has_env, inputs.as_slice(), output);
- let llfn = decl_fn(ccx, name, lib::llvm::CCallConv, llfty, output);
+ let llfn = decl_fn(ccx, name, llvm::CCallConv, llfty, output);
let attrs = get_fn_llvm_attributes(ccx, fn_ty);
for &(idx, attr) in attrs.iter() {
unsafe {
pub fn decl_internal_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str) -> ValueRef {
let llfn = decl_rust_fn(ccx, fn_ty, name);
- lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
+ llvm::SetLinkage(llfn, llvm::InternalLinkage);
llfn
}
Ok(id) => id,
Err(s) => {
bcx.sess().fatal(format!("allocation of `{}` {}",
- bcx.ty_to_str(info_ty),
+ bcx.ty_to_string(info_ty),
s).as_slice());
}
}
#[allow(dead_code)] // useful
pub fn set_optimize_for_size(f: ValueRef) {
- lib::llvm::SetFunctionAttribute(f, lib::llvm::OptimizeForSizeAttribute)
+ llvm::SetFunctionAttribute(f, llvm::OptimizeForSizeAttribute)
}
pub fn set_no_inline(f: ValueRef) {
- lib::llvm::SetFunctionAttribute(f, lib::llvm::NoInlineAttribute)
+ llvm::SetFunctionAttribute(f, llvm::NoInlineAttribute)
}
#[allow(dead_code)] // useful
pub fn set_no_unwind(f: ValueRef) {
- lib::llvm::SetFunctionAttribute(f, lib::llvm::NoUnwindAttribute)
+ llvm::SetFunctionAttribute(f, llvm::NoUnwindAttribute)
}
// Tell LLVM to emit the information necessary to unwind the stack for the
// function f.
pub fn set_uwtable(f: ValueRef) {
- lib::llvm::SetFunctionAttribute(f, lib::llvm::UWTableAttribute)
+ llvm::SetFunctionAttribute(f, llvm::UWTableAttribute)
}
pub fn set_inline_hint(f: ValueRef) {
- lib::llvm::SetFunctionAttribute(f, lib::llvm::InlineHintAttribute)
+ llvm::SetFunctionAttribute(f, llvm::InlineHintAttribute)
}
pub fn set_llvm_fn_attrs(attrs: &[ast::Attribute], llfn: ValueRef) {
if contains_name(attrs, "cold") {
unsafe {
llvm::LLVMAddFunctionAttribute(llfn,
- lib::llvm::FunctionIndex as c_uint,
- lib::llvm::ColdAttribute as uint64_t)
+ llvm::FunctionIndex as c_uint,
+ llvm::ColdAttribute as uint64_t)
}
}
}
pub fn set_always_inline(f: ValueRef) {
- lib::llvm::SetFunctionAttribute(f, lib::llvm::AlwaysInlineAttribute)
+ llvm::SetFunctionAttribute(f, llvm::AlwaysInlineAttribute)
}
pub fn set_split_stack(f: ValueRef) {
"split-stack".with_c_str(|buf| {
- unsafe { llvm::LLVMAddFunctionAttrString(f, lib::llvm::FunctionIndex as c_uint, buf); }
+ unsafe { llvm::LLVMAddFunctionAttrString(f, llvm::FunctionIndex as c_uint, buf); }
})
}
pub fn unset_split_stack(f: ValueRef) {
"split-stack".with_c_str(|buf| {
- unsafe { llvm::LLVMRemoveFunctionAttrString(f, lib::llvm::FunctionIndex as c_uint, buf); }
+ unsafe { llvm::LLVMRemoveFunctionAttrString(f, llvm::FunctionIndex as c_uint, buf); }
})
}
get_extern_fn(ccx,
&mut *ccx.externs.borrow_mut(),
name.as_slice(),
- lib::llvm::CCallConv,
+ llvm::CCallConv,
llty,
dtor_ty)
}
// We don't need to do actual comparisons for nil.
// () == () holds but () < () does not.
match op {
- ast::BiEq | ast::BiLe | ast::BiGe => return C_i1(cx.ccx(), true),
- ast::BiNe | ast::BiLt | ast::BiGt => return C_i1(cx.ccx(), false),
+ ast::BiEq | ast::BiLe | ast::BiGe => return C_bool(cx.ccx(), true),
+ ast::BiNe | ast::BiLt | ast::BiGt => return C_bool(cx.ccx(), false),
// refinements would be nice
_ => die(cx)
}
}
floating_point => {
let cmp = match op {
- ast::BiEq => lib::llvm::RealOEQ,
- ast::BiNe => lib::llvm::RealUNE,
- ast::BiLt => lib::llvm::RealOLT,
- ast::BiLe => lib::llvm::RealOLE,
- ast::BiGt => lib::llvm::RealOGT,
- ast::BiGe => lib::llvm::RealOGE,
+ ast::BiEq => llvm::RealOEQ,
+ ast::BiNe => llvm::RealUNE,
+ ast::BiLt => llvm::RealOLT,
+ ast::BiLe => llvm::RealOLE,
+ ast::BiGt => llvm::RealOGT,
+ ast::BiGe => llvm::RealOGE,
_ => die(cx)
};
return FCmp(cx, cmp, lhs, rhs);
}
signed_int => {
let cmp = match op {
- ast::BiEq => lib::llvm::IntEQ,
- ast::BiNe => lib::llvm::IntNE,
- ast::BiLt => lib::llvm::IntSLT,
- ast::BiLe => lib::llvm::IntSLE,
- ast::BiGt => lib::llvm::IntSGT,
- ast::BiGe => lib::llvm::IntSGE,
+ ast::BiEq => llvm::IntEQ,
+ ast::BiNe => llvm::IntNE,
+ ast::BiLt => llvm::IntSLT,
+ ast::BiLe => llvm::IntSLE,
+ ast::BiGt => llvm::IntSGT,
+ ast::BiGe => llvm::IntSGE,
_ => die(cx)
};
return ICmp(cx, cmp, lhs, rhs);
}
unsigned_int => {
let cmp = match op {
- ast::BiEq => lib::llvm::IntEQ,
- ast::BiNe => lib::llvm::IntNE,
- ast::BiLt => lib::llvm::IntULT,
- ast::BiLe => lib::llvm::IntULE,
- ast::BiGt => lib::llvm::IntUGT,
- ast::BiGe => lib::llvm::IntUGE,
+ ast::BiEq => llvm::IntEQ,
+ ast::BiNe => llvm::IntNE,
+ ast::BiLt => llvm::IntULT,
+ ast::BiLe => llvm::IntULE,
+ ast::BiGt => llvm::IntUGT,
+ ast::BiGe => llvm::IntUGE,
_ => die(cx)
};
return ICmp(cx, cmp, lhs, rhs);
},
ty::ty_uint(_) | ty::ty_int(_) => {
let cmp = match op {
- ast::BiEq => lib::llvm::IntEQ,
- ast::BiNe => lib::llvm::IntNE,
- ast::BiLt => lib::llvm::IntSLT,
- ast::BiLe => lib::llvm::IntSLE,
- ast::BiGt => lib::llvm::IntSGT,
- ast::BiGe => lib::llvm::IntSGE,
+ ast::BiEq => llvm::IntEQ,
+ ast::BiNe => llvm::IntNE,
+ ast::BiLt => llvm::IntSLT,
+ ast::BiLe => llvm::IntSLE,
+ ast::BiGt => llvm::IntSGT,
+ ast::BiGe => llvm::IntSGE,
_ => cx.sess().bug("compare_simd_types: must be a comparison operator"),
};
let return_ty = Type::vector(&type_of(cx.ccx(), t), size as u64);
let variant_cx =
fcx.new_temp_block(
format!("enum-iter-variant-{}",
- variant.disr_val.to_str().as_slice())
+ variant.disr_val.to_string().as_slice())
.as_slice());
match adt::trans_case(cx, &*repr, variant.disr_val) {
_match::single_result(r) => {
let (is_zero, is_signed) = match ty::get(rhs_t).sty {
ty::ty_int(t) => {
let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0u64, false);
- (ICmp(cx, lib::llvm::IntEQ, rhs, zero), true)
+ (ICmp(cx, llvm::IntEQ, rhs, zero), true)
}
ty::ty_uint(t) => {
let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0u64, false);
- (ICmp(cx, lib::llvm::IntEQ, rhs, zero), false)
+ (ICmp(cx, llvm::IntEQ, rhs, zero), false)
}
_ => {
cx.sess().bug(format!("fail-if-zero on unexpected type: {}",
- ty_to_str(cx.tcx(), rhs_t)).as_slice());
+ ty_to_string(cx.tcx(), rhs_t)).as_slice());
}
};
let bcx = with_cond(cx, is_zero, |bcx| {
}
_ => unreachable!(),
};
- let minus_one = ICmp(bcx, lib::llvm::IntEQ, rhs,
+ let minus_one = ICmp(bcx, llvm::IntEQ, rhs,
C_integral(llty, -1, false));
with_cond(bcx, minus_one, |bcx| {
- let is_min = ICmp(bcx, lib::llvm::IntEQ, lhs,
+ let is_min = ICmp(bcx, llvm::IntEQ, lhs,
C_integral(llty, min, true));
with_cond(bcx, is_min, |bcx| {
controlflow::trans_fail(bcx, span,
ty::ty_bare_fn(ref fn_ty) => {
match fn_ty.abi.for_target(ccx.sess().targ_cfg.os,
ccx.sess().targ_cfg.arch) {
- Some(Rust) | Some(RustIntrinsic) => {
+ Some(Rust) => {
get_extern_rust_fn(ccx, t, name.as_slice(), did)
}
+ Some(RustIntrinsic) => {
+ ccx.sess().bug("unexpected intrinsic in trans_external_path")
+ }
Some(..) | None => {
foreign::register_foreign_item_fn(ccx, fn_ty.abi, t,
name.as_slice(), None)
debug!("invoke at ???");
}
Some(id) => {
- debug!("invoke at {}", bcx.tcx().map.node_to_str(id));
+ debug!("invoke at {}", bcx.tcx().map.node_to_string(id));
}
}
pub fn load_if_immediate(cx: &Block, v: ValueRef, t: ty::t) -> ValueRef {
let _icx = push_ctxt("load_if_immediate");
- if type_is_immediate(cx.ccx(), t) { return Load(cx, v); }
+ if type_is_immediate(cx.ccx(), t) { return load_ty(cx, v, t); }
return v;
}
+pub fn load_ty(cx: &Block, ptr: ValueRef, t: ty::t) -> ValueRef {
+ /*!
+ * Helper for loading values from memory. Does the necessary conversion if
+ * the in-memory type differs from the type used for SSA values. Also
+ * handles various special cases where the type gives us better information
+ * about what we are loading.
+ */
+ if type_is_zero_size(cx.ccx(), t) {
+ C_undef(type_of::type_of(cx.ccx(), t))
+ } else if ty::type_is_bool(t) {
+ Trunc(cx, LoadRangeAssert(cx, ptr, 0, 2, llvm::False), Type::i1(cx.ccx()))
+ } else if ty::type_is_char(t) {
+ // a char is a unicode codepoint, and so takes values from 0
+ // to 0x10FFFF inclusive only.
+ LoadRangeAssert(cx, ptr, 0, 0x10FFFF + 1, llvm::False)
+ } else {
+ Load(cx, ptr)
+ }
+}
+
+pub fn store_ty(cx: &Block, v: ValueRef, dst: ValueRef, t: ty::t) {
+ /*!
+ * Helper for storing values in memory. Does the necessary conversion if
+ * the in-memory type differs from the type used for SSA values.
+ */
+ if ty::type_is_bool(t) {
+ Store(cx, ZExt(cx, v, Type::i8(cx.ccx())), dst);
+ } else {
+ Store(cx, v, dst);
+ };
+}
+
pub fn ignore_lhs(_bcx: &Block, local: &ast::Local) -> bool {
match local.pat.node {
ast::PatWild => true, _ => false
let dst_ptr = PointerCast(cx, dst, Type::i8p(ccx));
let size = IntCast(cx, n_bytes, ccx.int_type);
let align = C_i32(ccx, align as i32);
- let volatile = C_i1(ccx, false);
+ let volatile = C_bool(ccx, false);
Call(cx, memcpy, [dst_ptr, src_ptr, size, align, volatile], []);
}
let llzeroval = C_u8(ccx, 0);
let size = machine::llsize_of(ccx, ty);
let align = C_i32(ccx, llalign_of_min(ccx, ty) as i32);
- let volatile = C_i1(ccx, false);
+ let volatile = C_bool(ccx, false);
b.call(llintrinsicfn, [llptr, llzeroval, size, align, volatile], []);
}
llvm::LLVMGetParam(fcx.llfn, 0)
} else {
let lloutputtype = type_of::type_of(fcx.ccx, output_type);
- let bcx = fcx.entry_bcx.borrow().clone().unwrap();
- Alloca(bcx, lloutputtype, "__make_return_pointer")
+ AllocaFcx(fcx, lloutputtype, "__make_return_pointer")
}
}
}
if id == -1 {
"".to_string()
} else {
- ccx.tcx.map.path_to_str(id).to_string()
+ ccx.tcx.map.path_to_string(id).to_string()
},
id, param_substs.repr(ccx.tcx()));
llfn: llfndecl,
llenv: None,
llretptr: Cell::new(None),
- entry_bcx: RefCell::new(None),
alloca_insert_pt: Cell::new(None),
llreturn: Cell::new(None),
personality: Cell::new(None),
/// and allocating space for the return pointer.
pub fn init_function<'a>(fcx: &'a FunctionContext<'a>,
skip_retptr: bool,
- output_type: ty::t) {
+ output_type: ty::t) -> &'a Block<'a> {
let entry_bcx = fcx.new_temp_block("entry-block");
- *fcx.entry_bcx.borrow_mut() = Some(entry_bcx);
-
// Use a dummy instruction as the insertion point for all allocas.
// This is later removed in FunctionContext::cleanup.
fcx.alloca_insert_pt.set(Some(unsafe {
fcx.llretptr.set(Some(make_return_pointer(fcx, substd_output_type)));
}
}
+
+ entry_bcx
}
// NB: must keep 4 fns in sync:
// Ties up the llstaticallocas -> llloadenv -> lltop edges,
// and builds the return block.
pub fn finish_fn<'a>(fcx: &'a FunctionContext<'a>,
- last_bcx: &'a Block<'a>) {
+ last_bcx: &'a Block<'a>,
+ retty: ty::t) {
let _icx = push_ctxt("finish_fn");
+ // This shouldn't need to recompute the return type,
+ // as new_fn_ctxt did it already.
+ let substd_retty = retty.substp(fcx.ccx.tcx(), fcx.param_substs);
+
let ret_cx = match fcx.llreturn.get() {
Some(llreturn) => {
if !last_bcx.terminated.get() {
}
None => last_bcx
};
- build_return_block(fcx, ret_cx);
+ build_return_block(fcx, ret_cx, substd_retty);
debuginfo::clear_source_location(fcx);
fcx.cleanup();
}
// Builds the return block for a function.
-pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block) {
+pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block, retty: ty::t) {
// Return the value if this function immediate; otherwise, return void.
if fcx.llretptr.get().is_none() || fcx.caller_expects_out_pointer {
return RetVoid(ret_cx);
retptr.erase_from_parent();
}
- retval
+ if ty::type_is_bool(retty) {
+ Trunc(ret_cx, retval, Type::i1(fcx.ccx))
+ } else {
+ retval
+ }
}
// Otherwise, load the return value from the ret slot
- None => Load(ret_cx, fcx.llretptr.get().unwrap())
+ None => load_ty(ret_cx, fcx.llretptr.get().unwrap(), retty)
};
-
Ret(ret_cx, retval);
}
param_substs,
Some(body.span),
&arena);
- init_function(&fcx, false, output_type);
+ let mut bcx = init_function(&fcx, false, output_type);
// cleanup scope for the incoming arguments
let arg_scope = fcx.push_custom_cleanup_scope();
- // Create the first basic block in the function and keep a handle on it to
- // pass to finish_fn later.
- let bcx_top = fcx.entry_bcx.borrow().clone().unwrap();
- let mut bcx = bcx_top;
let block_ty = node_id_type(bcx, body.id);
// Set up arguments to the function.
}
// Insert the mandatory first few basic blocks before lltop.
- finish_fn(&fcx, bcx);
+ finish_fn(&fcx, bcx, output_type);
}
// trans_fn: creates an LLVM function corresponding to a source language
param_substs: ¶m_substs,
id: ast::NodeId,
attrs: &[ast::Attribute]) {
- let _s = StatRecorder::new(ccx, ccx.tcx.map.path_to_str(id).to_string());
+ let _s = StatRecorder::new(ccx, ccx.tcx.map.path_to_string(id).to_string());
debug!("trans_fn(param_substs={})", param_substs.repr(ccx.tcx()));
let _icx = push_ctxt("trans_fn");
let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx(), id));
_ => ccx.sess().bug(
format!("trans_enum_variant_or_tuple_like_struct: \
unexpected ctor return type {}",
- ty_to_str(ccx.tcx(), ctor_ty)).as_slice())
+ ty_to_string(ccx.tcx(), ctor_ty)).as_slice())
};
let arena = TypedArena::new();
let fcx = new_fn_ctxt(ccx, llfndecl, ctor_id, false, result_ty,
param_substs, None, &arena);
- init_function(&fcx, false, result_ty);
+ let bcx = init_function(&fcx, false, result_ty);
let arg_tys = ty::ty_fn_args(ctor_ty);
let arg_datums = create_datums_for_fn_args(&fcx, arg_tys.as_slice());
- let bcx = fcx.entry_bcx.borrow().clone().unwrap();
-
if !type_is_zero_size(fcx.ccx, result_ty) {
let repr = adt::represent_type(ccx, result_ty);
adt::trans_start_init(bcx, &*repr, fcx.llretptr.get().unwrap(), disr);
}
}
- finish_fn(&fcx, bcx);
+ finish_fn(&fcx, bcx, result_ty);
}
fn trans_enum_def(ccx: &CrateContext, enum_definition: &ast::EnumDef,
ccx.item_symbols.borrow_mut().insert(node_id, sym);
if !ccx.reachable.contains(&node_id) {
- lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
+ llvm::SetLinkage(llfn, llvm::InternalLinkage);
}
// The stack exhaustion lang item shouldn't have a split stack because
let def = ast_util::local_def(node_id);
if ccx.tcx.lang_items.stack_exhausted() == Some(def) {
unset_split_stack(llfn);
- lib::llvm::SetLinkage(llfn, lib::llvm::ExternalLinkage);
+ llvm::SetLinkage(llfn, llvm::ExternalLinkage);
}
if ccx.tcx.lang_items.eh_personality() == Some(def) {
- lib::llvm::SetLinkage(llfn, lib::llvm::ExternalLinkage);
+ llvm::SetLinkage(llfn, llvm::ExternalLinkage);
}
-> ValueRef {
match ty::get(node_type).sty {
ty::ty_bare_fn(ref f) => {
- assert!(f.abi == Rust || f.abi == RustIntrinsic);
+ assert!(f.abi == Rust);
}
- _ => fail!("expected bare rust fn or an intrinsic")
+ _ => fail!("expected bare rust fn")
};
let llfn = decl_rust_fn(ccx, node_type, sym.as_slice());
// implications directly to the call instruction. Right now,
// the only attribute we need to worry about is `sret`.
if type_of::return_uses_outptr(ccx, ret_ty) {
- attrs.push((1, lib::llvm::StructRetAttribute as u64));
+ attrs.push((1, llvm::StructRetAttribute as u64));
// The outptr can be noalias and nocapture because it's entirely
// invisible to the program. We can also mark it as nonnull
- attrs.push((1, lib::llvm::NoAliasAttribute as u64));
- attrs.push((1, lib::llvm::NoCaptureAttribute as u64));
- attrs.push((1, lib::llvm::NonNullAttribute as u64));
+ attrs.push((1, llvm::NoAliasAttribute as u64));
+ attrs.push((1, llvm::NoCaptureAttribute as u64));
+ attrs.push((1, llvm::NonNullAttribute as u64));
// Add one more since there's an outptr
first_arg_offset += 1;
ty::ty_str | ty::ty_vec(..) | ty::ty_trait(..) => true, _ => false
} => {}
ty::ty_uniq(_) => {
- attrs.push((lib::llvm::ReturnIndex as uint, lib::llvm::NoAliasAttribute as u64));
+ attrs.push((llvm::ReturnIndex as uint, llvm::NoAliasAttribute as u64));
}
_ => {}
}
ty::ty_str | ty::ty_vec(..) | ty::ty_trait(..) => true, _ => false
} => {}
ty::ty_uniq(_) | ty::ty_rptr(_, _) => {
- attrs.push((lib::llvm::ReturnIndex as uint, lib::llvm::NonNullAttribute as u64));
+ attrs.push((llvm::ReturnIndex as uint, llvm::NonNullAttribute as u64));
}
_ => {}
}
match ty::get(ret_ty).sty {
ty::ty_bool => {
- attrs.push((lib::llvm::ReturnIndex as uint, lib::llvm::ZExtAttribute as u64));
+ attrs.push((llvm::ReturnIndex as uint, llvm::ZExtAttribute as u64));
}
_ => {}
}
// For non-immediate arguments the callee gets its own copy of
// the value on the stack, so there are no aliases. It's also
// program-invisible so can't possibly capture
- attrs.push((idx, lib::llvm::NoAliasAttribute as u64));
- attrs.push((idx, lib::llvm::NoCaptureAttribute as u64));
- attrs.push((idx, lib::llvm::NonNullAttribute as u64));
+ attrs.push((idx, llvm::NoAliasAttribute as u64));
+ attrs.push((idx, llvm::NoCaptureAttribute as u64));
+ attrs.push((idx, llvm::NonNullAttribute as u64));
}
ty::ty_bool => {
- attrs.push((idx, lib::llvm::ZExtAttribute as u64));
+ attrs.push((idx, llvm::ZExtAttribute as u64));
}
// `~` pointer parameters never alias because ownership is transferred
ty::ty_uniq(_) => {
- attrs.push((idx, lib::llvm::NoAliasAttribute as u64));
- attrs.push((idx, lib::llvm::NonNullAttribute as u64));
+ attrs.push((idx, llvm::NoAliasAttribute as u64));
+ attrs.push((idx, llvm::NonNullAttribute as u64));
}
// `&mut` pointer parameters never alias other parameters, or mutable global data
ty::ty_rptr(b, mt) if mt.mutbl == ast::MutMutable => {
- attrs.push((idx, lib::llvm::NoAliasAttribute as u64));
- attrs.push((idx, lib::llvm::NonNullAttribute as u64));
+ attrs.push((idx, llvm::NoAliasAttribute as u64));
+ attrs.push((idx, llvm::NonNullAttribute as u64));
match b {
ReLateBound(_, BrAnon(_)) => {
- attrs.push((idx, lib::llvm::NoCaptureAttribute as u64));
+ attrs.push((idx, llvm::NoCaptureAttribute as u64));
}
_ => {}
}
// When a reference in an argument has no named lifetime, it's impossible for that
// reference to escape this function (returned or stored beyond the call by a closure).
ty::ty_rptr(ReLateBound(_, BrAnon(_)), _) => {
- attrs.push((idx, lib::llvm::NoCaptureAttribute as u64));
- attrs.push((idx, lib::llvm::NonNullAttribute as u64));
+ attrs.push((idx, llvm::NoCaptureAttribute as u64));
+ attrs.push((idx, llvm::NonNullAttribute as u64));
}
// & pointer parameters are never null
ty::ty_rptr(_, _) => {
- attrs.push((idx, lib::llvm::NonNullAttribute as u64));
+ attrs.push((idx, llvm::NonNullAttribute as u64));
}
_ => ()
}
sp: Span,
sym: String,
node_id: ast::NodeId,
- cc: lib::llvm::CallConv,
+ cc: llvm::CallConv,
llfty: Type) -> ValueRef {
debug!("register_fn_llvmty id={} sym={}", node_id, sym);
_ => ccx.tcx.map.with_path(id, |mut path| {
if attr::contains_name(attrs, "no_mangle") {
// Don't mangle
- path.last().unwrap().to_str()
+ path.last().unwrap().to_string()
} else {
match weak_lang_items::link_name(attrs) {
Some(name) => name.get().to_string(),
});
if !ccx.reachable.contains(&id) {
- lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage);
+ llvm::SetLinkage(g, llvm::InternalLinkage);
}
// Apply the `unnamed_addr` attribute if
if !ast_util::static_has_significant_address(
mutbl,
i.attrs.as_slice()) {
- lib::llvm::SetUnnamedAddr(g, true);
+ llvm::SetUnnamedAddr(g, true);
// This is a curious case where we must make
// all of these statics inlineable. If a
if attr::contains_name(i.attrs.as_slice(),
"thread_local") {
- lib::llvm::set_thread_local(g, true);
+ llvm::set_thread_local(g, true);
}
if !inlineable {
// linkage b/c that doesn't quite make sense. Otherwise items can
// have internal linkage if they're not reachable.
if !foreign && !ccx.reachable.contains(&id) {
- lib::llvm::SetLinkage(val, lib::llvm::InternalLinkage);
+ llvm::SetLinkage(val, llvm::InternalLinkage);
}
ccx.item_vals.borrow_mut().insert(id, val);
}.as_slice());
let llmeta = C_bytes(cx, compressed.as_slice());
let llconst = C_struct(cx, [llmeta], false);
- let name = format!("rust_metadata_{}_{}_{}", cx.link_meta.crateid.name,
- cx.link_meta.crateid.version_or_default(), cx.link_meta.crate_hash);
+ let name = format!("rust_metadata_{}_{}",
+ cx.link_meta.crate_name,
+ cx.link_meta.crate_hash);
let llglobal = name.with_c_str(|buf| {
unsafe {
llvm::LLVMAddGlobal(cx.metadata_llmod, val_ty(llconst).to_ref(), buf)
}
pub fn trans_crate(krate: ast::Crate,
- analysis: CrateAnalysis,
- output: &OutputFilenames) -> (ty::ctxt, CrateTranslation) {
- let CrateAnalysis { ty_cx: tcx, exp_map2, reachable, .. } = analysis;
+ analysis: CrateAnalysis) -> (ty::ctxt, CrateTranslation) {
+ let CrateAnalysis { ty_cx: tcx, exp_map2, reachable, name, .. } = analysis;
// Before we touch LLVM, make sure that multithreading is enabled.
unsafe {
}
}
- let link_meta = link::build_link_meta(&krate,
- output.out_filestem.as_slice());
+ let link_meta = link::build_link_meta(&tcx.sess, &krate, name);
// Append ".rs" to crate name as LLVM module identifier.
//
// crashes if the module identifier is same as other symbols
// such as a function name in the module.
// 1. http://llvm.org/bugs/show_bug.cgi?id=11479
- let mut llmod_id = link_meta.crateid.name.clone();
+ let mut llmod_id = link_meta.crate_name.clone();
llmod_id.push_str(".rs");
let ccx = CrateContext::new(llmod_id.as_slice(), tcx, exp_map2,
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use lib::llvm::{llvm, BasicBlockRef};
+use llvm;
+use llvm::{BasicBlockRef};
use middle::trans::value::{Users, Value};
use std::iter::{Filter, Map};
#![allow(dead_code)] // FFI wrappers
#![allow(non_snake_case_functions)]
-use lib::llvm::llvm;
-use lib::llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect};
-use lib::llvm::{Opcode, IntPredicate, RealPredicate};
-use lib::llvm::{ValueRef, BasicBlockRef};
-use lib;
+use llvm;
+use llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect};
+use llvm::{Opcode, IntPredicate, RealPredicate};
+use llvm::{ValueRef, BasicBlockRef};
use middle::trans::common::*;
use syntax::codemap::Span;
pub fn AddCase(s: ValueRef, on_val: ValueRef, dest: BasicBlockRef) {
unsafe {
- if llvm::LLVMIsUndef(s) == lib::llvm::True { return; }
+ if llvm::LLVMIsUndef(s) == llvm::True { return; }
llvm::LLVMAddCase(s, on_val, dest);
}
}
check_not_terminated(cx);
terminate(cx, "Invoke");
debug!("Invoke({} with arguments ({}))",
- cx.val_to_str(fn_),
- args.iter().map(|a| cx.val_to_str(*a)).collect::<Vec<String>>().connect(", "));
+ cx.val_to_string(fn_),
+ args.iter().map(|a| cx.val_to_string(*a)).collect::<Vec<String>>().connect(", "));
B(cx).invoke(fn_, args, then, catch, attributes)
}
let ccx = cx.fcx.ccx;
if cx.unreachable.get() {
let ty = val_ty(pointer_val);
- let eltty = if ty.kind() == lib::llvm::Array {
+ let eltty = if ty.kind() == llvm::Array {
ty.element_type()
} else {
ccx.int_type
pub fn LoadRangeAssert(cx: &Block, pointer_val: ValueRef, lo: c_ulonglong,
- hi: c_ulonglong, signed: lib::llvm::Bool) -> ValueRef {
+ hi: c_ulonglong, signed: llvm::Bool) -> ValueRef {
if cx.unreachable.get() {
let ccx = cx.fcx.ccx;
let ty = val_ty(pointer_val);
- let eltty = if ty.kind() == lib::llvm::Array {
+ let eltty = if ty.kind() == llvm::Array {
ty.element_type()
} else {
ccx.int_type
pub fn AddIncomingToPhi(phi: ValueRef, val: ValueRef, bb: BasicBlockRef) {
unsafe {
- if llvm::LLVMIsUndef(phi) == lib::llvm::True { return; }
+ if llvm::LLVMIsUndef(phi) == llvm::True { return; }
llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint);
}
}
unsafe {
let ccx = cx.fcx.ccx;
let ty = val_ty(fn_);
- let retty = if ty.kind() == lib::llvm::Integer {
+ let retty = if ty.kind() == llvm::Integer {
ty.return_type()
} else {
ccx.int_type
#![allow(dead_code)] // FFI wrappers
-use lib;
-use lib::llvm::llvm;
-use lib::llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect};
-use lib::llvm::{Opcode, IntPredicate, RealPredicate, False};
-use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef};
+use llvm;
+use llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect};
+use llvm::{Opcode, IntPredicate, RealPredicate, False};
+use llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef};
use middle::trans::base;
use middle::trans::common::*;
use middle::trans::machine::llalign_of_pref;
self.count_insn("invoke");
debug!("Invoke {} with args ({})",
- self.ccx.tn.val_to_str(llfn),
+ self.ccx.tn.val_to_string(llfn),
args.iter()
- .map(|&v| self.ccx.tn.val_to_str(v))
+ .map(|&v| self.ccx.tn.val_to_string(v))
.collect::<Vec<String>>()
.connect(", "));
self.count_insn("load.volatile");
unsafe {
let insn = llvm::LLVMBuildLoad(self.llbuilder, ptr, noname());
- llvm::LLVMSetVolatile(insn, lib::llvm::True);
+ llvm::LLVMSetVolatile(insn, llvm::True);
insn
}
}
pub fn load_range_assert(&self, ptr: ValueRef, lo: c_ulonglong,
- hi: c_ulonglong, signed: lib::llvm::Bool) -> ValueRef {
+ hi: c_ulonglong, signed: llvm::Bool) -> ValueRef {
let value = self.load(ptr);
unsafe {
let v = [min, max];
- llvm::LLVMSetMetadata(value, lib::llvm::MD_range as c_uint,
+ llvm::LLVMSetMetadata(value, llvm::MD_range as c_uint,
llvm::LLVMMDNodeInContext(self.ccx.llcx,
v.as_ptr(), v.len() as c_uint));
}
pub fn store(&self, val: ValueRef, ptr: ValueRef) {
debug!("Store {} -> {}",
- self.ccx.tn.val_to_str(val),
- self.ccx.tn.val_to_str(ptr));
+ self.ccx.tn.val_to_string(val),
+ self.ccx.tn.val_to_string(ptr));
assert!(self.llbuilder.is_not_null());
self.count_insn("store");
unsafe {
pub fn volatile_store(&self, val: ValueRef, ptr: ValueRef) {
debug!("Store {} -> {}",
- self.ccx.tn.val_to_str(val),
- self.ccx.tn.val_to_str(ptr));
+ self.ccx.tn.val_to_string(val),
+ self.ccx.tn.val_to_string(ptr));
assert!(self.llbuilder.is_not_null());
self.count_insn("store.volatile");
unsafe {
let insn = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
- llvm::LLVMSetVolatile(insn, lib::llvm::True);
+ llvm::LLVMSetVolatile(insn, llvm::True);
}
}
pub fn atomic_store(&self, val: ValueRef, ptr: ValueRef, order: AtomicOrdering) {
debug!("Store {} -> {}",
- self.ccx.tn.val_to_str(val),
- self.ccx.tn.val_to_str(ptr));
+ self.ccx.tn.val_to_string(val),
+ self.ccx.tn.val_to_string(ptr));
self.count_insn("store.atomic");
unsafe {
let ty = Type::from_ref(llvm::LLVMTypeOf(ptr));
if self.ccx.sess().asm_comments() {
let s = format!("{} ({})",
text,
- self.ccx.sess().codemap().span_to_str(sp));
+ self.ccx.sess().codemap().span_to_string(sp));
debug!("{}", s.as_slice());
self.add_comment(s.as_slice());
}
dia: AsmDialect) -> ValueRef {
self.count_insn("inlineasm");
- let volatile = if volatile { lib::llvm::True }
- else { lib::llvm::False };
- let alignstack = if alignstack { lib::llvm::True }
- else { lib::llvm::False };
+ let volatile = if volatile { llvm::True }
+ else { llvm::False };
+ let alignstack = if alignstack { llvm::True }
+ else { llvm::False };
let argtys = inputs.iter().map(|v| {
- debug!("Asm Input Type: {:?}", self.ccx.tn.val_to_str(*v));
+ debug!("Asm Input Type: {:?}", self.ccx.tn.val_to_string(*v));
val_ty(*v)
}).collect::<Vec<_>>();
- debug!("Asm Output Type: {:?}", self.ccx.tn.type_to_str(output));
+ debug!("Asm Output Type: {:?}", self.ccx.tn.type_to_string(output));
let fty = Type::func(argtys.as_slice(), &output);
unsafe {
let v = llvm::LLVMInlineAsm(
self.count_insn("call");
debug!("Call {} with args ({})",
- self.ccx.tn.val_to_str(llfn),
+ self.ccx.tn.val_to_string(llfn),
args.iter()
- .map(|&v| self.ccx.tn.val_to_str(v))
+ .map(|&v| self.ccx.tn.val_to_string(v))
.collect::<Vec<String>>()
.connect(", "));
conv: CallConv, attributes: &[(uint, u64)]) -> ValueRef {
self.count_insn("callwithconv");
let v = self.call(llfn, args, attributes);
- lib::llvm::SetInstructionCallConv(v, conv);
+ llvm::SetInstructionCallConv(v, conv);
v
}
pub fn set_cleanup(&self, landing_pad: ValueRef) {
self.count_insn("setcleanup");
unsafe {
- llvm::LLVMSetCleanup(landing_pad, lib::llvm::True);
+ llvm::LLVMSetCleanup(landing_pad, llvm::True);
}
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use lib::llvm::Attribute;
+use llvm::Attribute;
use std::option;
use middle::trans::context::CrateContext;
use middle::trans::cabi_x86;
#![allow(non_uppercase_pattern_statics)]
-use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array};
-use lib::llvm::{StructRetAttribute, ZExtAttribute};
+use llvm;
+use llvm::{Integer, Pointer, Float, Double, Struct, Array};
+use llvm::{StructRetAttribute, ZExtAttribute};
use middle::trans::cabi::{FnType, ArgType};
use middle::trans::context::CrateContext;
use middle::trans::type_::Type;
fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
if is_reg_ty(ty) {
- let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+ let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
return ArgType::direct(ty, None, None, attr);
}
let size = ty_size(ty);
fn classify_arg_ty(ccx: &CrateContext, ty: Type) -> ArgType {
if is_reg_ty(ty) {
- let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+ let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
return ArgType::direct(ty, None, None, attr);
}
let align = ty_align(ty);
use libc::c_uint;
use std::cmp;
-use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array};
-use lib::llvm::{StructRetAttribute, ZExtAttribute};
+use llvm;
+use llvm::{Integer, Pointer, Float, Double, Struct, Array};
+use llvm::{StructRetAttribute, ZExtAttribute};
use middle::trans::context::CrateContext;
use middle::trans::cabi::*;
use middle::trans::type_::Type;
fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
if is_reg_ty(ty) {
- let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+ let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
ArgType::direct(ty, None, None, attr)
} else {
ArgType::indirect(ty, Some(StructRetAttribute))
*offset += align_up_to(size, align * 8) / 8;
if is_reg_ty(ty) {
- let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+ let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
ArgType::direct(ty, None, None, attr)
} else {
ArgType::direct(
use syntax::abi::{OsWin32, OsMacos, OsiOS};
-use lib::llvm::*;
+use llvm::*;
use super::cabi::*;
use super::common::*;
use super::machine::*;
}
}
} else {
- let attr = if rty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+ let attr = if rty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
ret_ty = ArgType::direct(rty, None, None, attr);
}
}
}
_ => {
- let attr = if t == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+ let attr = if t == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
ArgType::direct(t, None, None, attr)
}
};
#![allow(non_uppercase_pattern_statics)]
-use lib::llvm::{llvm, Integer, Pointer, Float, Double};
-use lib::llvm::{Struct, Array, Attribute};
-use lib::llvm::{StructRetAttribute, ByValAttribute, ZExtAttribute};
+use llvm;
+use llvm::{Integer, Pointer, Float, Double};
+use llvm::{Struct, Array, Attribute};
+use llvm::{StructRetAttribute, ByValAttribute, ZExtAttribute};
use middle::trans::cabi::*;
use middle::trans::context::CrateContext;
use middle::trans::type_::Type;
None)
}
} else {
- let attr = if ty == Type::bool(ccx) { Some(ZExtAttribute) } else { None };
+ let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
ArgType::direct(ty, None, None, attr)
}
}
use arena::TypedArena;
use back::abi;
use back::link;
-use driver::session;
-use lib::llvm::ValueRef;
-use lib::llvm::llvm;
+use llvm;
+use llvm::ValueRef;
use metadata::csearch;
use middle::def;
use middle::subst;
use middle::trans::glue;
use middle::trans::inline;
use middle::trans::foreign;
+use middle::trans::intrinsic;
use middle::trans::meth;
use middle::trans::monomorphize;
use middle::trans::type_::Type;
use std::gc::Gc;
use syntax::ast;
use synabi = syntax::abi;
-use syntax::ast_map;
pub struct MethodData {
pub llfn: ValueRef,
// value (which is a pair).
Fn(/* llfn */ ValueRef),
+ Intrinsic(ast::NodeId, subst::Substs),
+
TraitMethod(MethodData)
}
expr.span,
format!("type of callee is neither bare-fn nor closure: \
{}",
- bcx.ty_to_str(datum.ty)).as_slice());
+ bcx.ty_to_string(datum.ty)).as_slice());
}
}
}
fn trans_def<'a>(bcx: &'a Block<'a>, def: def::Def, ref_expr: &ast::Expr)
-> Callee<'a> {
+ debug!("trans_def(def={}, ref_expr={})", def.repr(bcx.tcx()), ref_expr.repr(bcx.tcx()));
+ let expr_ty = node_id_type(bcx, ref_expr.id);
match def {
+ def::DefFn(did, _) if match ty::get(expr_ty).sty {
+ ty::ty_bare_fn(ref f) => f.abi == synabi::RustIntrinsic,
+ _ => false
+ } => {
+ let substs = node_id_substs(bcx, ExprId(ref_expr.id));
+ let def_id = if did.krate != ast::LOCAL_CRATE {
+ inline::maybe_instantiate_inline(bcx.ccx(), did)
+ } else {
+ did
+ };
+ Callee { bcx: bcx, data: Intrinsic(def_id.node, substs) }
+ }
def::DefFn(did, _) |
def::DefStaticMethod(did, def::FromImpl(_), _) => {
fn_callee(bcx, trans_fn_ref(bcx, did, ExprId(ref_expr.id)))
bcx.tcx(), ¶m_substs, &impl_res);
// Now we pull any vtables for parameters on the actual method.
- param_vtables
- .get_mut_vec(subst::FnSpace)
- .push_all(
- impl_vtables.get_vec(subst::FnSpace).as_slice());
+ param_vtables.push_all(subst::FnSpace,
+ impl_vtables.get_slice(subst::FnSpace));
param_vtables
}
&empty_param_substs,
None,
&block_arena);
- init_function(&fcx, false, return_type);
+ let mut bcx = init_function(&fcx, false, return_type);
// Create the substituted versions of the self type.
- let mut bcx = fcx.entry_bcx.borrow().clone().unwrap();
let arg_scope = fcx.push_custom_cleanup_scope();
let arg_scope_id = cleanup::CustomScope(arg_scope);
let boxed_arg_types = ty::ty_fn_args(boxed_function_type);
}).bcx;
bcx = fcx.pop_and_trans_custom_cleanup_scope(bcx, arg_scope);
- finish_fn(&fcx, bcx);
+ finish_fn(&fcx, bcx, return_type);
llfn
}
}
};
- // We must monomorphise if the fn has type parameters, is a rust
- // intrinsic, or is a default method. In particular, if we see an
- // intrinsic that is inlined from a different crate, we want to reemit the
- // intrinsic instead of trying to call it in the other crate.
- let must_monomorphise = if !substs.types.is_empty() || is_default {
- true
- } else if def_id.krate == ast::LOCAL_CRATE {
- let map_node = session::expect(
- ccx.sess(),
- tcx.map.find(def_id.node),
- || "local item should be in ast map".to_string());
-
- match map_node {
- ast_map::NodeForeignItem(_) => {
- tcx.map.get_foreign_abi(def_id.node) == synabi::RustIntrinsic
- }
- _ => false
- }
- } else {
- false
- };
+ // We must monomorphise if the fn has type parameters or is a default method.
+ let must_monomorphise = !substs.types.is_empty() || is_default;
// Create a monomorphic version of generic functions
if must_monomorphise {
let callee = get_callee(bcx, cleanup::CustomScope(arg_cleanup_scope));
let mut bcx = callee.bcx;
+ let (abi, ret_ty) = match ty::get(callee_ty).sty {
+ ty::ty_bare_fn(ref f) => (f.abi, f.sig.output),
+ ty::ty_closure(ref f) => (synabi::Rust, f.sig.output),
+ _ => fail!("expected bare rust fn or closure in trans_call_inner")
+ };
+
let (llfn, llenv, llself) = match callee.data {
Fn(llfn) => {
(llfn, None, None)
let llenv = Load(bcx, llenv);
(llfn, Some(llenv), None)
}
- };
+ Intrinsic(node, substs) => {
+ assert!(abi == synabi::RustIntrinsic);
+ assert!(dest.is_some());
- let (abi, ret_ty) = match ty::get(callee_ty).sty {
- ty::ty_bare_fn(ref f) => (f.abi, f.sig.output),
- ty::ty_closure(ref f) => (synabi::Rust, f.sig.output),
- _ => fail!("expected bare rust fn or closure in trans_call_inner")
+ return intrinsic::trans_intrinsic_call(bcx, node, callee_ty,
+ arg_cleanup_scope, args,
+ dest.unwrap(), substs);
+ }
};
- let is_rust_fn = abi == synabi::Rust || abi == synabi::RustIntrinsic;
+
+ // Intrinsics should not become actual functions.
+ // We trans them in place in `trans_intrinsic_call`
+ assert!(abi != synabi::RustIntrinsic);
// Generate a location to store the result. If the user does
// not care about the result, just make a stack slot.
// and done, either the return value of the function will have been
// written in opt_llretslot (if it is Some) or `llresult` will be
// set appropriately (otherwise).
- if is_rust_fn {
+ if abi == synabi::Rust {
let mut llargs = Vec::new();
// Push the out-pointer if we use an out-pointer for this
if !type_of::return_uses_outptr(bcx.ccx(), ret_ty) &&
!type_is_zero_size(bcx.ccx(), ret_ty)
{
- Store(bcx, llret, llretslot);
+ store_ty(bcx, llret, llretslot, ret_ty)
}
}
None => {}
ArgOverloadedOp(Datum<Expr>, Option<(Datum<Expr>, ast::NodeId)>),
}
-fn trans_args<'a>(cx: &'a Block<'a>,
- args: CallArgs,
- fn_ty: ty::t,
- llargs: &mut Vec<ValueRef> ,
- arg_cleanup_scope: cleanup::ScopeId,
- ignore_self: bool)
- -> &'a Block<'a> {
+pub fn trans_args<'a>(cx: &'a Block<'a>,
+ args: CallArgs,
+ fn_ty: ty::t,
+ llargs: &mut Vec<ValueRef> ,
+ arg_cleanup_scope: cleanup::ScopeId,
+ ignore_self: bool)
+ -> &'a Block<'a> {
let _icx = push_ctxt("trans_args");
let arg_tys = ty::ty_fn_args(fn_ty);
let variadic = ty::fn_is_variadic(fn_ty);
let arg_datum_ty = arg_datum.ty;
- debug!(" arg datum: {}", arg_datum.to_str(bcx.ccx()));
+ debug!(" arg datum: {}", arg_datum.to_string(bcx.ccx()));
let mut val;
if ty::type_is_bot(arg_datum_ty) {
// this could happen due to e.g. subtyping
let llformal_arg_ty = type_of::type_of_explicit_arg(ccx, formal_arg_ty);
debug!("casting actual type ({}) to match formal ({})",
- bcx.val_to_str(val), bcx.llty_str(llformal_arg_ty));
+ bcx.val_to_string(val), bcx.llty_str(llformal_arg_ty));
val = PointerCast(bcx, val, llformal_arg_ty);
}
}
- debug!("--- trans_arg_datum passing {}", bcx.val_to_str(val));
+ debug!("--- trans_arg_datum passing {}", bcx.val_to_string(val));
Result::new(bcx, val)
}
* drop glue. See discussion in `doc.rs` for a high-level summary.
*/
-use lib::llvm::{BasicBlockRef, ValueRef};
+use llvm::{BasicBlockRef, ValueRef};
use middle::trans::base;
use middle::trans::build;
use middle::trans::callee;
*/
debug!("push_ast_cleanup_scope({})",
- self.ccx.tcx.map.node_to_str(id));
+ self.ccx.tcx.map.node_to_string(id));
// FIXME(#2202) -- currently closure bodies have a parent
// region, which messes up the assertion below, since there
id: ast::NodeId,
exits: [&'a Block<'a>, ..EXIT_MAX]) {
debug!("push_loop_cleanup_scope({})",
- self.ccx.tcx.map.node_to_str(id));
+ self.ccx.tcx.map.node_to_string(id));
assert_eq!(Some(id), self.top_ast_scope());
self.push_scope(CleanupScope::new(LoopScopeKind(id, exits)));
*/
debug!("pop_and_trans_ast_cleanup_scope({})",
- self.ccx.tcx.map.node_to_str(cleanup_scope));
+ self.ccx.tcx.map.node_to_string(cleanup_scope));
assert!(self.top_scope(|s| s.kind.is_ast_with_id(cleanup_scope)));
*/
debug!("pop_loop_cleanup_scope({})",
- self.ccx.tcx.map.node_to_str(cleanup_scope));
+ self.ccx.tcx.map.node_to_string(cleanup_scope));
assert!(self.top_scope(|s| s.kind.is_loop_with_id(cleanup_scope)));
is_immediate: false,
on_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
val: val,
- ty: ty
+ ty: ty,
+ zero: false
};
debug!("schedule_drop_mem({:?}, val={}, ty={})",
cleanup_scope,
- self.ccx.tn.val_to_str(val),
+ self.ccx.tn.val_to_string(val),
ty.repr(self.ccx.tcx()));
self.schedule_clean(cleanup_scope, drop as Box<Cleanup>);
}
+ fn schedule_drop_and_zero_mem(&self,
+ cleanup_scope: ScopeId,
+ val: ValueRef,
+ ty: ty::t) {
+ /*!
+ * Schedules a (deep) drop and zero-ing of `val`, which is a pointer
+ * to an instance of `ty`
+ */
+
+ if !ty::type_needs_drop(self.ccx.tcx(), ty) { return; }
+ let drop = box DropValue {
+ is_immediate: false,
+ on_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
+ val: val,
+ ty: ty,
+ zero: true
+ };
+
+ debug!("schedule_drop_and_zero_mem({:?}, val={}, ty={}, zero={})",
+ cleanup_scope,
+ self.ccx.tn.val_to_string(val),
+ ty.repr(self.ccx.tcx()),
+ true);
+
+ self.schedule_clean(cleanup_scope, drop as Box<Cleanup>);
+ }
+
fn schedule_drop_immediate(&self,
cleanup_scope: ScopeId,
val: ValueRef,
is_immediate: true,
on_unwind: ty::type_needs_unwind_cleanup(self.ccx.tcx(), ty),
val: val,
- ty: ty
+ ty: ty,
+ zero: false
};
debug!("schedule_drop_immediate({:?}, val={}, ty={})",
cleanup_scope,
- self.ccx.tn.val_to_str(val),
+ self.ccx.tn.val_to_string(val),
ty.repr(self.ccx.tcx()));
self.schedule_clean(cleanup_scope, drop as Box<Cleanup>);
debug!("schedule_free_value({:?}, val={}, heap={:?})",
cleanup_scope,
- self.ccx.tn.val_to_str(val),
+ self.ccx.tn.val_to_string(val),
heap);
self.schedule_clean(cleanup_scope, drop as Box<Cleanup>);
self.ccx.sess().bug(
format!("no cleanup scope {} found",
- self.ccx.tcx.map.node_to_str(cleanup_scope)).as_slice());
+ self.ccx.tcx.map.node_to_string(cleanup_scope)).as_slice());
}
fn schedule_clean_in_custom_scope(&self,
on_unwind: bool,
val: ValueRef,
ty: ty::t,
+ zero: bool
}
impl Cleanup for DropValue {
}
fn trans<'a>(&self, bcx: &'a Block<'a>) -> &'a Block<'a> {
- if self.is_immediate {
+ let bcx = if self.is_immediate {
glue::drop_ty_immediate(bcx, self.val, self.ty)
} else {
glue::drop_ty(bcx, self.val, self.ty)
+ };
+ if self.zero {
+ base::zero_mem(bcx, self.val, self.ty);
}
+ bcx
}
}
cleanup_scope: ScopeId,
val: ValueRef,
ty: ty::t);
+ fn schedule_drop_and_zero_mem(&self,
+ cleanup_scope: ScopeId,
+ val: ValueRef,
+ ty: ty::t);
fn schedule_drop_immediate(&self,
cleanup_scope: ScopeId,
val: ValueRef,
use back::abi;
use back::link::mangle_internal_name_by_path_and_seq;
use driver::config::FullDebugInfo;
-use lib::llvm::ValueRef;
+use llvm::ValueRef;
use middle::def;
use middle::freevars;
use middle::lang_items::ClosureExchangeMallocFnLangItem;
use middle::trans::type_::Type;
use middle::ty;
use util::ppaux::Repr;
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
use arena::TypedArena;
use syntax::ast;
}
impl EnvValue {
- pub fn to_str(&self, ccx: &CrateContext) -> String {
- format!("{}({})", self.action, self.datum.to_str(ccx))
+ pub fn to_string(&self, ccx: &CrateContext) -> String {
+ format!("{}({})", self.action, self.datum.to_string(ccx))
}
}
}
}).collect();
let cdata_ty = ty::mk_tup(tcx, bound_tys);
- debug!("cdata_ty={}", ty_to_str(tcx, cdata_ty));
+ debug!("cdata_ty={}", ty_to_string(tcx, cdata_ty));
return cdata_ty;
}
let Result {bcx: bcx, val: llbox} = allocate_cbox(bcx, store, cdata_ty);
let llbox = PointerCast(bcx, llbox, llboxptr_ty);
- debug!("tuplify_box_ty = {}", ty_to_str(tcx, cbox_ty));
+ debug!("tuplify_box_ty = {}", ty_to_string(tcx, cbox_ty));
// Copy expr values into boxed bindings.
let mut bcx = bcx;
for (i, bv) in bound_values.move_iter().enumerate() {
- debug!("Copy {} into closure", bv.to_str(ccx));
+ debug!("Copy {} into closure", bv.to_string(ccx));
if ccx.sess().asm_comments() {
add_comment(bcx, format!("Copy {} into closure",
- bv.to_str(ccx)).as_slice());
+ bv.to_string(ccx)).as_slice());
}
let bound_data = GEPi(bcx, llbox, [0u, abi::box_field_body, i]);
let empty_param_substs = param_substs::empty();
let fcx = new_fn_ctxt(ccx, llfn, -1, true, f.sig.output,
&empty_param_substs, None, &arena);
- init_function(&fcx, true, f.sig.output);
- let bcx = fcx.entry_bcx.borrow().clone().unwrap();
+ let bcx = init_function(&fcx, true, f.sig.output);
let args = create_datums_for_fn_args(&fcx,
ty::ty_fn_args(closure_ty)
//! Code that is useful in various trans modules.
use driver::session::Session;
-use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef};
-use lib::llvm::{True, False, Bool};
-use lib::llvm::llvm;
-use lib;
+use llvm;
+use llvm::{ValueRef, BasicBlockRef, BuilderRef};
+use llvm::{True, False, Bool};
use middle::def;
use middle::lang_items::LangItem;
use middle::subst;
}
}
-fn param_substs_to_str(this: ¶m_substs, tcx: &ty::ctxt) -> String {
+fn param_substs_to_string(this: ¶m_substs, tcx: &ty::ctxt) -> String {
format!("param_substs({})", this.substs.repr(tcx))
}
impl Repr for param_substs {
fn repr(&self, tcx: &ty::ctxt) -> String {
- param_substs_to_str(self, tcx)
+ param_substs_to_string(self, tcx)
}
}
// always be Some.
pub llretptr: Cell<Option<ValueRef>>,
- pub entry_bcx: RefCell<Option<&'a Block<'a>>>,
-
// These pub elements: "hoisted basic blocks" containing
// administrative activities that have to happen in only one place in
// the function, due to LLVM's quirks.
.get()
.unwrap());
}
- // Remove the cycle between fcx and bcx, so memory can be freed
- *self.entry_bcx.borrow_mut() = None;
}
pub fn get_llreturn(&self) -> BasicBlockRef {
token::get_ident(ident).get().to_string()
}
- pub fn node_id_to_str(&self, id: ast::NodeId) -> String {
- self.tcx().map.node_to_str(id).to_string()
+ pub fn node_id_to_string(&self, id: ast::NodeId) -> String {
+ self.tcx().map.node_to_string(id).to_string()
}
- pub fn expr_to_str(&self, e: &ast::Expr) -> String {
+ pub fn expr_to_string(&self, e: &ast::Expr) -> String {
e.repr(self.tcx())
}
}
}
- pub fn val_to_str(&self, val: ValueRef) -> String {
- self.ccx().tn.val_to_str(val)
+ pub fn val_to_string(&self, val: ValueRef) -> String {
+ self.ccx().tn.val_to_string(val)
}
pub fn llty_str(&self, ty: Type) -> String {
- self.ccx().tn.type_to_str(ty)
+ self.ccx().tn.type_to_string(ty)
}
- pub fn ty_to_str(&self, t: ty::t) -> String {
+ pub fn ty_to_string(&self, t: ty::t) -> String {
t.repr(self.tcx())
}
}
pub fn C_bool(ccx: &CrateContext, val: bool) -> ValueRef {
- C_integral(Type::bool(ccx), val as u64, false)
-}
-
-pub fn C_i1(ccx: &CrateContext, val: bool) -> ValueRef {
C_integral(Type::i1(ccx), val as u64, false)
}
});
llvm::LLVMSetInitializer(g, sc);
llvm::LLVMSetGlobalConstant(g, True);
- lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage);
+ llvm::SetLinkage(g, llvm::InternalLinkage);
cx.const_cstr_cache.borrow_mut().insert(s, g);
g
});
llvm::LLVMSetInitializer(g, lldata);
llvm::LLVMSetGlobalConstant(g, True);
- lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage);
+ llvm::SetLinkage(g, llvm::InternalLinkage);
let cs = llvm::LLVMConstPointerCast(g, Type::i8p(cx).to_ref());
C_struct(cx, [cs, C_uint(cx, len)], false)
let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint);
debug!("const_get_elt(v={}, us={:?}, r={})",
- cx.tn.val_to_str(v), us, cx.tn.val_to_str(r));
+ cx.tn.val_to_string(v), us, cx.tn.val_to_string(r));
return r;
}
use back::abi;
-use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool, True,
+use llvm;
+use llvm::{ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool, True,
False};
-use lib::llvm::{IntEQ, IntNE, IntUGT, IntUGE, IntULT, IntULE, IntSGT, IntSGE, IntSLT, IntSLE,
+use llvm::{IntEQ, IntNE, IntUGT, IntUGE, IntULT, IntULE, IntSGT, IntSGE, IntSLT, IntSLE,
RealOEQ, RealOGT, RealOGE, RealOLT, RealOLE, RealONE};
use metadata::csearch;
use middle::trans::type_of;
use middle::trans::debuginfo;
use middle::ty;
-use util::ppaux::{Repr, ty_to_str};
+use util::ppaux::{Repr, ty_to_string};
use std::c_str::ToCStr;
use std::gc::Gc;
pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: ast::Lit)
-> ValueRef {
let _icx = push_ctxt("trans_lit");
+ debug!("const_lit: {}", lit);
match lit.node {
ast::LitByte(b) => C_integral(Type::uint_from_ty(cx, ast::TyU8), b as u64, false),
ast::LitChar(i) => C_integral(Type::char(cx), i as u64, false),
_ => cx.sess().span_bug(lit.span,
format!("integer literal has type {} (expected int \
or uint)",
- ty_to_str(cx.tcx(), lit_int_ty)).as_slice())
+ ty_to_string(cx.tcx(), lit_int_ty)).as_slice())
}
}
ast::LitFloat(ref fs, t) => {
}
_ => {
cx.sess().bug(format!("unexpected dereferenceable type {}",
- ty_to_str(cx.tcx(), t)).as_slice())
+ ty_to_string(cx.tcx(), t)).as_slice())
}
};
(dv, mt.ty)
}
None => {
cx.sess().bug(format!("can't dereference const of type {}",
- ty_to_str(cx.tcx(), t)).as_slice())
+ ty_to_string(cx.tcx(), t)).as_slice())
}
}
}
llvm::LLVMDumpValue(C_undef(llty));
}
cx.sess().bug(format!("const {} of type {} has size {} instead of {}",
- e.repr(cx.tcx()), ty_to_str(cx.tcx(), ety),
+ e.repr(cx.tcx()), ty_to_string(cx.tcx(), ety),
csize, tsize).as_slice());
}
(llconst, inlineable)
if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty.to_ref()) }
else { llvm::LLVMConstFPToUI(v, llty.to_ref()) }
}
- (expr::cast_enum, expr::cast_integral) |
- (expr::cast_enum, expr::cast_float) => {
+ (expr::cast_enum, expr::cast_integral) => {
let repr = adt::represent_type(cx, basety);
let discr = adt::const_get_discrim(cx, &*repr, v);
let iv = C_integral(cx.int_type, discr, false);
use driver::config::NoDebugInfo;
use driver::session::Session;
-use lib::llvm::{ContextRef, ModuleRef, ValueRef};
-use lib::llvm::{llvm, TargetData, TypeNames};
-use lib::llvm::mk_target_data;
+use llvm;
+use llvm::{ContextRef, ModuleRef, ValueRef};
+use llvm::{TargetData};
+use llvm::mk_target_data;
use metadata::common::LinkMeta;
use middle::resolve;
use middle::trans::adt;
use middle::trans::common::{ExternMap,tydesc_info,BuilderRef_res};
use middle::trans::debuginfo;
use middle::trans::monomorphize::MonoId;
-use middle::trans::type_::Type;
+use middle::trans::type_::{Type, TypeNames};
use middle::ty;
use util::sha2::Sha256;
use util::nodemap::{NodeMap, NodeSet, DefIdMap};
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use lib::llvm::*;
+use llvm::*;
use driver::config::FullDebugInfo;
use middle::def;
use middle::lang_items::{FailFnLangItem, FailBoundsCheckFnLangItem};
dest: expr::Dest)
-> &'a Block<'a> {
debug!("trans_if(bcx={}, if_id={}, cond={}, thn={:?}, dest={})",
- bcx.to_str(), if_id, bcx.expr_to_str(cond), thn.id,
- dest.to_str(bcx.ccx()));
+ bcx.to_str(), if_id, bcx.expr_to_string(cond), thn.id,
+ dest.to_string(bcx.ccx()));
let _icx = push_ctxt("trans_if");
let mut bcx = bcx;
* Datums are and how they are intended to be used.
*/
-use lib;
-use lib::llvm::ValueRef;
+use llvm::ValueRef;
use middle::trans::base::*;
-use middle::trans::build::*;
use middle::trans::common::*;
use middle::trans::cleanup;
use middle::trans::cleanup::CleanupMethods;
use middle::trans::tvec;
use middle::trans::type_of;
use middle::ty;
-use util::ppaux::{ty_to_str};
+use util::ppaux::{ty_to_string};
use syntax::ast;
match self.kind.mode {
ByValue => DatumBlock::new(bcx, self),
ByRef => {
- let llval = load(bcx, self.val, self.ty);
+ let llval = load_ty(bcx, self.val, self.ty);
DatumBlock::new(bcx, Datum::new(llval, self.ty, Rvalue::new(ByValue)))
}
}
DatumBlock::new(bcx, scratch)
}
ByValue => {
- let v = load(bcx, l.val, l.ty);
+ let v = load_ty(bcx, l.val, l.ty);
bcx = l.kind.post_store(bcx, l.val, l.ty);
DatumBlock::new(bcx, Datum::new(v, l.ty, Rvalue::new(ByValue)))
}
}
}
-fn load<'a>(bcx: &'a Block<'a>, llptr: ValueRef, ty: ty::t) -> ValueRef {
- /*!
- * Private helper for loading from a by-ref datum. Handles various
- * special cases where the type gives us better information about
- * what we are loading.
- */
-
- if type_is_zero_size(bcx.ccx(), ty) {
- C_undef(type_of::type_of(bcx.ccx(), ty))
- } else if ty::type_is_char(ty) {
- // a char is a unicode codepoint, and so takes values from 0
- // to 0x10FFFF inclusive only.
- LoadRangeAssert(bcx, llptr, 0, 0x10FFFF + 1, lib::llvm::False)
- } else {
- Load(bcx, llptr)
- }
-}
-
/**
* Generic methods applicable to any sort of datum.
*/
if self.kind.is_by_ref() {
memcpy_ty(bcx, dst, self.val, self.ty);
} else {
- Store(bcx, self.val, dst);
+ store_ty(bcx, self.val, dst, self.ty);
}
return bcx;
}
#[allow(dead_code)] // useful for debugging
- pub fn to_str(&self, ccx: &CrateContext) -> String {
+ pub fn to_string(&self, ccx: &CrateContext) -> String {
format!("Datum({}, {}, {:?})",
- ccx.tn.val_to_str(self.val),
- ty_to_str(ccx.tcx(), self.ty),
+ ccx.tn.val_to_string(self.val),
+ ty_to_string(ccx.tcx(), self.ty),
self.kind)
}
assert!(!ty::type_needs_drop(bcx.tcx(), self.ty));
assert!(self.appropriate_rvalue_mode(bcx.ccx()) == ByValue);
if self.kind.is_by_ref() {
- load(bcx, self.val, self.ty)
+ load_ty(bcx, self.val, self.ty)
} else {
self.val
}
use driver::config;
use driver::config::{FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
-use lib::llvm::llvm;
-use lib::llvm::{ModuleRef, ContextRef, ValueRef};
-use lib::llvm::debuginfo::*;
+use llvm;
+use llvm::{ModuleRef, ContextRef, ValueRef};
+use llvm::debuginfo::*;
use metadata::csearch;
use middle::subst;
use middle::trans::adt;
metadata: DIType) {
if !self.type_to_metadata.insert(ty::type_id(type_), metadata) {
cx.sess().bug(format!("Type metadata for ty::t '{}' is already in the TypeMap!",
- ppaux::ty_to_str(cx.tcx(), type_)).as_slice());
+ ppaux::ty_to_string(cx.tcx(), type_)).as_slice());
}
}
},
_ => {
cx.sess().bug(format!("get_unique_type_id_of_type() - unexpected type: {}, {:?}",
- ppaux::ty_to_str(cx.tcx(), type_).as_slice(),
+ ppaux::ty_to_string(cx.tcx(), type_).as_slice(),
ty::get(type_).sty).as_slice())
}
};
// Maybe check that there is no self type here.
- let tps = substs.types.get_vec(subst::TypeSpace);
+ let tps = substs.types.get_slice(subst::TypeSpace);
if tps.len() > 0 {
output.push_char('<');
let type_metadata = type_metadata(cx, variable_type, span);
let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
- let var_name = token::get_ident(ident).get().to_str();
+ let var_name = token::get_ident(ident).get().to_string();
let linkage_name =
namespace_node.mangled_name_of_contained_item(var_name.as_slice());
let var_scope = namespace_node.scope;
FunctionDebugContext(box ref function_debug_context) => {
let cx = fcx.ccx;
- debug!("set_source_location: {}", cx.sess().codemap().span_to_str(span));
+ debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span));
if function_debug_context.source_locations_enabled.get() {
let loc = span_start(cx, span);
}
}
ast_map::NodeMethod(ref method) => {
- (method.ident,
- method.decl,
- &method.generics,
- method.body,
+ (ast_util::method_ident(&**method),
+ ast_util::method_fn_decl(&**method),
+ ast_util::method_generics(&**method),
+ ast_util::method_body(&**method),
method.span,
true)
}
ast_map::NodeTraitMethod(ref trait_method) => {
match **trait_method {
ast::Provided(ref method) => {
- (method.ident,
- method.decl,
- &method.generics,
- method.body,
+ (ast_util::method_ident(&**method),
+ ast_util::method_fn_decl(&**method),
+ ast_util::method_generics(&**method),
+ ast_util::method_body(&**method),
method.span,
true)
}
}
// Handle other generic parameters
- let actual_types = param_substs.substs.types.get_vec(subst::FnSpace);
+ let actual_types = param_substs.substs.types.get_slice(subst::FnSpace);
for (index, &ast::TyParam{ ident: ident, .. }) in generics.ty_params.iter().enumerate() {
- let actual_type = *actual_types.get(index);
+ let actual_type = actual_types[index];
// Add actual type name to <...> clause of function name
let actual_type_name = compute_debuginfo_type_name(cx,
actual_type,
});
fn fallback_path(cx: &CrateContext) -> CString {
- cx.link_meta.crateid.name.as_slice().to_c_str()
+ cx.link_meta.crate_name.as_slice().to_c_str()
}
}
type_map.find_metadata_for_type(unfinished_type).is_none() {
cx.sess().bug(format!("Forward declaration of potentially recursive type \
'{}' was not found in TypeMap!",
- ppaux::ty_to_str(cx.tcx(), unfinished_type))
+ ppaux::ty_to_string(cx.tcx(), unfinished_type))
.as_slice());
}
}
let null_variant_index = (1 - nndiscr) as uint;
let null_variant_ident = self.variants.get(null_variant_index).name;
let null_variant_name = token::get_ident(null_variant_ident);
+ let discrfield = match ptrfield {
+ adt::ThinPointer(field) => format!("{}", field),
+ adt::FatPointer(field, pair) => format!("{}${}", field, pair)
+ };
let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
- ptrfield,
+ discrfield,
null_variant_name);
// Create the (singleton) list of descriptions of union members.
enum EnumDiscriminantInfo {
RegularDiscriminant(DIType),
- OptimizedDiscriminant(uint),
+ OptimizedDiscriminant(adt::PointerField),
NoDiscriminant
}
Some(ref names) => {
names.iter()
.map(|ident| {
- token::get_ident(*ident).get().to_str().into_string()
+ token::get_ident(*ident).get().to_string().into_string()
}).collect()
}
None => variant_info.args.iter().map(|_| "".to_string()).collect()
ty::ty_uniq(pointee_type) => pointee_type,
ty::ty_rptr(_, ty::mt { ty, .. }) => ty,
_ => {
- let pp_type_name = ppaux::ty_to_str(cx.tcx(), trait_pointer_type);
+ let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_pointer_type);
cx.sess().bug(format!("debuginfo: Unexpected trait-pointer type in \
trait_pointer_metadata(): {}",
pp_type_name.as_slice()).as_slice());
let def_id = match ty::get(trait_object_type).sty {
ty::ty_trait(box ty::TyTrait { def_id, .. }) => def_id,
_ => {
- let pp_type_name = ppaux::ty_to_str(cx.tcx(), trait_object_type);
+ let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_object_type);
cx.sess().bug(format!("debuginfo: Unexpected trait-object type in \
trait_pointer_metadata(): {}",
pp_type_name.as_slice()).as_slice());
the debuginfo::TypeMap but it \
was not. (ty::t = {})",
unique_type_id_str.as_slice(),
- ppaux::ty_to_str(cx.tcx(), t));
+ ppaux::ty_to_string(cx.tcx(), t));
cx.sess().span_bug(usage_site_span, error_message.as_slice());
}
};
debuginfo::TypeMap. \
UniqueTypeId={}, ty::t={}",
unique_type_id_str.as_slice(),
- ppaux::ty_to_str(cx.tcx(), t));
+ ppaux::ty_to_string(cx.tcx(), t));
cx.sess().span_bug(usage_site_span, error_message.as_slice());
}
}
ty::ty_infer(_) |
ty::ty_param(_) => {
cx.sess().bug(format!("debuginfo: Trying to create type name for \
- unexpected type: {}", ppaux::ty_to_str(cx.tcx(), t)).as_slice());
+ unexpected type: {}", ppaux::ty_to_string(cx.tcx(), t)).as_slice());
}
}
}
fn crate_root_namespace<'a>(cx: &'a CrateContext) -> &'a str {
- cx.link_meta.crateid.name.as_slice()
+ cx.link_meta.crate_name.as_slice()
}
fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTreeNode> {
#![allow(non_camel_case_types)]
use back::abi;
-use lib::llvm::{ValueRef, llvm};
-use lib;
+use llvm;
+use llvm::{ValueRef};
use metadata::csearch;
use middle::def;
use middle::lang_items::MallocFnLangItem;
use syntax::ast;
use syntax::codemap;
-use syntax::print::pprust::{expr_to_str};
+use syntax::print::pprust::{expr_to_string};
use std::gc::Gc;
}
impl Dest {
- pub fn to_str(&self, ccx: &CrateContext) -> String {
+ pub fn to_string(&self, ccx: &CrateContext) -> String {
match *self {
- SaveIn(v) => format!("SaveIn({})", ccx.tn.val_to_str(v)),
+ SaveIn(v) => format!("SaveIn({})", ccx.tn.val_to_string(v)),
Ignore => "Ignore".to_string()
}
}
* the stack.
*/
- debug!("trans(expr={})", bcx.expr_to_str(expr));
+ debug!("trans(expr={})", bcx.expr_to_string(expr));
let mut bcx = bcx;
let fcx = bcx.fcx;
Some(adj) => { adj }
};
debug!("unadjusted datum for expr {}: {}",
- expr.id, datum.to_str(bcx.ccx()));
+ expr.id, datum.to_string(bcx.ccx()));
match adjustment {
AutoAddEnv(..) => {
datum = unpack_datum!(bcx, add_env(bcx, expr, datum));
datum = scratch.to_expr_datum();
}
}
- debug!("after adjustments, datum={}", datum.to_str(bcx.ccx()));
+ debug!("after adjustments, datum={}", datum.to_string(bcx.ccx()));
return DatumBlock {bcx: bcx, datum: datum};
fn auto_slice<'a>(
let mut bcx = bcx;
- debug!("trans_unadjusted(expr={})", bcx.expr_to_str(expr));
+ debug!("trans_unadjusted(expr={})", bcx.expr_to_string(expr));
let _indenter = indenter();
debuginfo::set_source_location(bcx.fcx, expr.id, expr.span);
trans_rec_field(bcx, &**base, ident.node)
}
ast::ExprIndex(ref base, ref idx) => {
- trans_index(bcx, expr, &**base, &**idx)
+ trans_index(bcx, expr, &**base, &**idx, MethodCall::expr(expr.id))
}
ast::ExprVstore(ref contents, ast::ExprVstoreUniq) => {
fcx.push_ast_cleanup_scope(contents.id);
fn trans_index<'a>(bcx: &'a Block<'a>,
index_expr: &ast::Expr,
base: &ast::Expr,
- idx: &ast::Expr)
+ idx: &ast::Expr,
+ method_call: MethodCall)
-> DatumBlock<'a, Expr> {
//! Translates `base[idx]`.
let ccx = bcx.ccx();
let mut bcx = bcx;
- let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, base, "index"));
-
- // Translate index expression and cast to a suitable LLVM integer.
- // Rust is less strict than LLVM in this regard.
- let ix_datum = unpack_datum!(bcx, trans(bcx, idx));
- let ix_val = ix_datum.to_llscalarish(bcx);
- let ix_size = machine::llbitsize_of_real(bcx.ccx(), val_ty(ix_val));
- let int_size = machine::llbitsize_of_real(bcx.ccx(), ccx.int_type);
- let ix_val = {
- if ix_size < int_size {
- if ty::type_is_signed(expr_ty(bcx, idx)) {
- SExt(bcx, ix_val, ccx.int_type)
- } else { ZExt(bcx, ix_val, ccx.int_type) }
- } else if ix_size > int_size {
- Trunc(bcx, ix_val, ccx.int_type)
- } else {
- ix_val
- }
- };
+ // Check for overloaded index.
+ let method_ty = ccx.tcx
+ .method_map
+ .borrow()
+ .find(&method_call)
+ .map(|method| method.ty);
+ let elt_datum = match method_ty {
+ Some(method_ty) => {
+ let base_datum = unpack_datum!(bcx, trans(bcx, base));
- let vt = tvec::vec_types(bcx, ty::sequence_element_type(bcx.tcx(), base_datum.ty));
- base::maybe_name_value(bcx.ccx(), vt.llunit_size, "unit_sz");
+ // Translate index expression.
+ let ix_datum = unpack_datum!(bcx, trans(bcx, idx));
- let (base, len) = base_datum.get_vec_base_and_len(bcx);
+ // Overloaded. Evaluate `trans_overloaded_op`, which will
+ // invoke the user's index() method, which basically yields
+ // a `&T` pointer. We can then proceed down the normal
+ // path (below) to dereference that `&T`.
+ let val =
+ unpack_result!(bcx,
+ trans_overloaded_op(bcx,
+ index_expr,
+ method_call,
+ base_datum,
+ Some((ix_datum, idx.id)),
+ None));
+ let ref_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty));
+ let elt_ty = match ty::deref(ref_ty, true) {
+ None => {
+ bcx.tcx().sess.span_bug(index_expr.span,
+ "index method didn't return a \
+ dereferenceable type?!")
+ }
+ Some(elt_tm) => elt_tm.ty,
+ };
+ Datum::new(val, elt_ty, LvalueExpr)
+ }
+ None => {
+ let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx,
+ base,
+ "index"));
+
+ // Translate index expression and cast to a suitable LLVM integer.
+ // Rust is less strict than LLVM in this regard.
+ let ix_datum = unpack_datum!(bcx, trans(bcx, idx));
+ let ix_val = ix_datum.to_llscalarish(bcx);
+ let ix_size = machine::llbitsize_of_real(bcx.ccx(),
+ val_ty(ix_val));
+ let int_size = machine::llbitsize_of_real(bcx.ccx(),
+ ccx.int_type);
+ let ix_val = {
+ if ix_size < int_size {
+ if ty::type_is_signed(expr_ty(bcx, idx)) {
+ SExt(bcx, ix_val, ccx.int_type)
+ } else { ZExt(bcx, ix_val, ccx.int_type) }
+ } else if ix_size > int_size {
+ Trunc(bcx, ix_val, ccx.int_type)
+ } else {
+ ix_val
+ }
+ };
- debug!("trans_index: base {}", bcx.val_to_str(base));
- debug!("trans_index: len {}", bcx.val_to_str(len));
+ let vt =
+ tvec::vec_types(bcx,
+ ty::sequence_element_type(bcx.tcx(),
+ base_datum.ty));
+ base::maybe_name_value(bcx.ccx(), vt.llunit_size, "unit_sz");
+
+ let (base, len) = base_datum.get_vec_base_and_len(bcx);
+
+ debug!("trans_index: base {}", bcx.val_to_string(base));
+ debug!("trans_index: len {}", bcx.val_to_string(len));
+
+ let bounds_check = ICmp(bcx, llvm::IntUGE, ix_val, len);
+ let expect = ccx.get_intrinsic(&("llvm.expect.i1"));
+ let expected = Call(bcx,
+ expect,
+ [bounds_check, C_bool(ccx, false)],
+ []);
+ bcx = with_cond(bcx, expected, |bcx| {
+ controlflow::trans_fail_bounds_check(bcx,
+ index_expr.span,
+ ix_val,
+ len)
+ });
+ let elt = InBoundsGEP(bcx, base, [ix_val]);
+ let elt = PointerCast(bcx, elt, vt.llunit_ty.ptr_to());
+ Datum::new(elt, vt.unit_ty, LvalueExpr)
+ }
+ };
- let bounds_check = ICmp(bcx, lib::llvm::IntUGE, ix_val, len);
- let expect = ccx.get_intrinsic(&("llvm.expect.i1"));
- let expected = Call(bcx, expect, [bounds_check, C_i1(ccx, false)], []);
- let bcx = with_cond(bcx, expected, |bcx| {
- controlflow::trans_fail_bounds_check(bcx, index_expr.span, ix_val, len)
- });
- let elt = InBoundsGEP(bcx, base, [ix_val]);
- let elt = PointerCast(bcx, elt, vt.llunit_ty.ptr_to());
- DatumBlock::new(bcx, Datum::new(elt, vt.unit_ty, LvalueExpr))
+ DatumBlock::new(bcx, elt_datum)
}
fn trans_def<'a>(bcx: &'a Block<'a>,
let expr_ty = expr_ty(bcx, expr);
let store = ty::ty_closure_store(expr_ty);
debug!("translating block function {} with type {}",
- expr_to_str(expr), expr_ty.repr(tcx));
+ expr_to_string(expr), expr_ty.repr(tcx));
closure::trans_expr_fn(bcx, store, &**decl, &**body, expr.id, dest)
}
ast::ExprCall(ref f, ref args) => {
_ => {
bcx.tcx().sess.span_bug(ref_expr.span, format!(
"Non-DPS def {:?} referened by {}",
- def, bcx.node_id_to_str(ref_expr.id)).as_slice());
+ def, bcx.node_id_to_string(ref_expr.id)).as_slice());
}
}
}
}
};
debug!("take_local(nid={:?}, v={}, ty={})",
- nid, bcx.val_to_str(datum.val), bcx.ty_to_str(datum.ty));
+ nid, bcx.val_to_string(datum.val), bcx.ty_to_string(datum.ty));
datum
}
}
match op {
ast::UnNot => {
let datum = unpack_datum!(bcx, trans(bcx, sub_expr));
- let llresult = if ty::type_is_bool(un_ty) {
- let val = datum.to_llscalarish(bcx);
- Xor(bcx, val, C_bool(ccx, true))
- } else {
- // Note: `Not` is bitwise, not suitable for logical not.
- Not(bcx, datum.to_llscalarish(bcx))
- };
+ let llresult = Not(bcx, datum.to_llscalarish(bcx));
immediate_rvalue_bcx(bcx, llresult, un_ty).to_expr_datumblock()
}
ast::UnNeg => {
}
Br(past_rhs, join.llbb);
- let phi = Phi(join, Type::bool(bcx.ccx()), [lhs, rhs],
+ let phi = Phi(join, Type::i1(bcx.ccx()), [lhs, rhs],
[past_lhs.llbb, past_rhs.llbb]);
return immediate_rvalue_bcx(join, phi, binop_ty).to_expr_datumblock();
debug!("trans_binary (expr {}): lhs_datum={}",
expr.id,
- lhs_datum.to_str(ccx));
+ lhs_datum.to_string(ccx));
let lhs_ty = lhs_datum.ty;
let lhs = lhs_datum.to_llscalarish(bcx);
debug!("trans_binary (expr {}): rhs_datum={}",
expr.id,
- rhs_datum.to_str(ccx));
+ rhs_datum.to_string(ccx));
let rhs_ty = rhs_datum.ty;
let rhs = rhs_datum.to_llscalarish(bcx);
trans_eager_binop(bcx, expr, binop_ty, op,
let k_in = cast_type_kind(t_in);
let k_out = cast_type_kind(t_out);
let s_in = k_in == cast_integral && ty::type_is_signed(t_in);
- let ll_t_in = type_of::type_of(ccx, t_in);
- let ll_t_out = type_of::type_of(ccx, t_out);
+ let ll_t_in = type_of::arg_type_of(ccx, t_in);
+ let ll_t_out = type_of::arg_type_of(ccx, t_out);
// Convert the value to be cast into a ValueRef, either by-ref or
// by-value as appropriate given its type:
let _icx = push_ctxt("trans_assign_op");
let mut bcx = bcx;
- debug!("trans_assign_op(expr={})", bcx.expr_to_str(expr));
+ debug!("trans_assign_op(expr={})", bcx.expr_to_string(expr));
// User-defined operator methods cannot be used with `+=` etc right now
assert!(!bcx.tcx().method_map.borrow().contains_key(&MethodCall::expr(expr.id)));
let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, dst, "assign_op"));
assert!(!ty::type_needs_drop(bcx.tcx(), dst_datum.ty));
let dst_ty = dst_datum.ty;
- let dst = Load(bcx, dst_datum.val);
+ let dst = load_ty(bcx, dst_datum.val, dst_datum.ty);
// Evaluate RHS
let rhs_datum = unpack_datum!(bcx, trans(bcx, &*src));
debug!("deref_once(expr={}, datum={}, method_call={})",
expr.repr(bcx.tcx()),
- datum.to_str(ccx),
+ datum.to_string(ccx),
method_call);
let mut bcx = bcx;
Some(method_ty) => {
// Overloaded. Evaluate `trans_overloaded_op`, which will
// invoke the user's deref() method, which basically
- // converts from the `Shaht<T>` pointer that we have into
+ // converts from the `Smaht<T>` pointer that we have into
// a `&T` pointer. We can then proceed down the normal
// path (below) to dereference that `&T`.
let datum = match method_call.adjustment {
};
debug!("deref_once(expr={}, method_call={}, result={})",
- expr.id, method_call, r.datum.to_str(ccx));
+ expr.id, method_call, r.datum.to_string(ccx));
return r;
use back::{link};
-use lib::llvm::llvm;
-use lib::llvm::{ValueRef, CallConv, Linkage};
-use lib;
+use llvm;
+use llvm::{ValueRef, CallConv, Linkage};
use middle::weak_lang_items;
use middle::trans::base::push_ctxt;
use middle::trans::base;
use middle::trans::build::*;
-use middle::trans::builder::noname;
use middle::trans::cabi;
use middle::trans::common::*;
use middle::trans::machine;
abi.for_target(os, arch).map(|abi| {
match abi {
RustIntrinsic => {
- // Intrinsics are emitted by monomorphic fn
+ // Intrinsics are emitted at the call site
ccx.sess().bug("asked to register intrinsic fn");
}
// It's the ABI's job to select this, not us.
System => ccx.sess().bug("system abi should be selected elsewhere"),
- Stdcall => lib::llvm::X86StdcallCallConv,
- Fastcall => lib::llvm::X86FastcallCallConv,
- C => lib::llvm::CCallConv,
- Win64 => lib::llvm::X86_64_Win64,
+ Stdcall => llvm::X86StdcallCallConv,
+ Fastcall => llvm::X86FastcallCallConv,
+ C => llvm::CCallConv,
+ Win64 => llvm::X86_64_Win64,
// These API constants ought to be more specific...
- Cdecl => lib::llvm::CCallConv,
- Aapcs => lib::llvm::CCallConv,
+ Cdecl => llvm::CCallConv,
+ Aapcs => llvm::CCallConv,
}
})
}
// ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
// and don't have to be, LLVM treats them as no-ops.
match name {
- "appending" => Some(lib::llvm::AppendingLinkage),
- "available_externally" => Some(lib::llvm::AvailableExternallyLinkage),
- "common" => Some(lib::llvm::CommonLinkage),
- "extern_weak" => Some(lib::llvm::ExternalWeakLinkage),
- "external" => Some(lib::llvm::ExternalLinkage),
- "internal" => Some(lib::llvm::InternalLinkage),
- "linkonce" => Some(lib::llvm::LinkOnceAnyLinkage),
- "linkonce_odr" => Some(lib::llvm::LinkOnceODRLinkage),
- "private" => Some(lib::llvm::PrivateLinkage),
- "weak" => Some(lib::llvm::WeakAnyLinkage),
- "weak_odr" => Some(lib::llvm::WeakODRLinkage),
+ "appending" => Some(llvm::AppendingLinkage),
+ "available_externally" => Some(llvm::AvailableExternallyLinkage),
+ "common" => Some(llvm::CommonLinkage),
+ "extern_weak" => Some(llvm::ExternalWeakLinkage),
+ "external" => Some(llvm::ExternalLinkage),
+ "internal" => Some(llvm::InternalLinkage),
+ "linkonce" => Some(llvm::LinkOnceAnyLinkage),
+ "linkonce_odr" => Some(llvm::LinkOnceODRLinkage),
+ "private" => Some(llvm::PrivateLinkage),
+ "weak" => Some(llvm::WeakAnyLinkage),
+ "weak_odr" => Some(llvm::WeakODRLinkage),
_ => None,
}
}
let g1 = ident.get().with_c_str(|buf| {
llvm::LLVMAddGlobal(ccx.llmod, llty2.to_ref(), buf)
});
- lib::llvm::SetLinkage(g1, linkage);
+ llvm::SetLinkage(g1, linkage);
let mut real_name = "_rust_extern_with_linkage_".to_string();
real_name.push_str(ident.get());
let g2 = real_name.with_c_str(|buf| {
llvm::LLVMAddGlobal(ccx.llmod, llty.to_ref(), buf)
});
- lib::llvm::SetLinkage(g2, lib::llvm::InternalLinkage);
+ llvm::SetLinkage(g2, llvm::InternalLinkage);
llvm::LLVMSetInitializer(g2, g1);
g2
}
// Make sure the calling convention is right for variadic functions
// (should've been caught if not in typeck)
if tys.fn_sig.variadic {
- assert!(cc == lib::llvm::CCallConv);
+ assert!(cc == llvm::CCallConv);
}
// Create the LLVM value for the C extern fn
llfn={}, \
llretptr={})",
callee_ty.repr(tcx),
- ccx.tn.val_to_str(llfn),
- ccx.tn.val_to_str(llretptr));
+ ccx.tn.val_to_string(llfn),
+ ccx.tn.val_to_string(llretptr));
let (fn_abi, fn_sig) = match ty::get(callee_ty).sty {
ty::ty_bare_fn(ref fn_ty) => (fn_ty.abi, fn_ty.sig.clone()),
debug!("argument {}, llarg_rust={}, rust_indirect={}, arg_ty={}",
i,
- ccx.tn.val_to_str(llarg_rust),
+ ccx.tn.val_to_string(llarg_rust),
rust_indirect,
- ccx.tn.type_to_str(arg_tys[i].ty));
+ ccx.tn.type_to_string(arg_tys[i].ty));
// Ensure that we always have the Rust value indirectly,
// because it makes bitcasting easier.
base::alloca(bcx,
type_of::type_of(ccx, *passed_arg_tys.get(i)),
"__arg");
- Store(bcx, llarg_rust, scratch);
+ base::store_ty(bcx, llarg_rust, scratch, *passed_arg_tys.get(i));
llarg_rust = scratch;
}
debug!("llarg_rust={} (after indirection)",
- ccx.tn.val_to_str(llarg_rust));
+ ccx.tn.val_to_string(llarg_rust));
// Check whether we need to do any casting
match arg_tys[i].cast {
}
debug!("llarg_rust={} (after casting)",
- ccx.tn.val_to_str(llarg_rust));
+ ccx.tn.val_to_string(llarg_rust));
// Finally, load the value if needed for the foreign ABI
let foreign_indirect = arg_tys[i].is_indirect();
let llarg_foreign = if foreign_indirect {
llarg_rust
} else {
- Load(bcx, llarg_rust)
+ if ty::type_is_bool(*passed_arg_tys.get(i)) {
+ let val = LoadRangeAssert(bcx, llarg_rust, 0, 2, llvm::False);
+ Trunc(bcx, val, Type::i1(bcx.ccx()))
+ } else {
+ Load(bcx, llarg_rust)
+ }
};
debug!("argument {}, llarg_foreign={}",
- i, ccx.tn.val_to_str(llarg_foreign));
+ i, ccx.tn.val_to_string(llarg_foreign));
// fill padding with undef value
match arg_tys[i].pad {
if fn_type.ret_ty.is_indirect() {
// The outptr can be noalias and nocapture because it's entirely
// invisible to the program. We can also mark it as nonnull
- attrs.push((1, lib::llvm::NoAliasAttribute as u64));
- attrs.push((1, lib::llvm::NoCaptureAttribute as u64));
- attrs.push((1, lib::llvm::NonNullAttribute as u64));
+ attrs.push((1, llvm::NoAliasAttribute as u64));
+ attrs.push((1, llvm::NoCaptureAttribute as u64));
+ attrs.push((1, llvm::NonNullAttribute as u64));
};
// Add attributes that depend on the concrete foreign ABI
None => fn_type.ret_ty.ty
};
- debug!("llretptr={}", ccx.tn.val_to_str(llretptr));
- debug!("llforeign_retval={}", ccx.tn.val_to_str(llforeign_retval));
- debug!("llrust_ret_ty={}", ccx.tn.type_to_str(llrust_ret_ty));
- debug!("llforeign_ret_ty={}", ccx.tn.type_to_str(llforeign_ret_ty));
+ debug!("llretptr={}", ccx.tn.val_to_string(llretptr));
+ debug!("llforeign_retval={}", ccx.tn.val_to_string(llforeign_retval));
+ debug!("llrust_ret_ty={}", ccx.tn.type_to_string(llrust_ret_ty));
+ debug!("llforeign_ret_ty={}", ccx.tn.type_to_string(llforeign_ret_ty));
if llrust_ret_ty == llforeign_ret_ty {
- Store(bcx, llforeign_retval, llretptr);
+ base::store_ty(bcx, llforeign_retval, llretptr, fn_sig.output)
} else {
// The actual return type is a struct, but the ABI
// adaptation code has cast it into some scalar type. The
let cconv = match ty::get(t).sty {
ty::ty_bare_fn(ref fn_ty) => {
let c = llvm_calling_convention(ccx, fn_ty.abi);
- c.unwrap_or(lib::llvm::CCallConv)
+ c.unwrap_or(llvm::CCallConv)
}
_ => fail!("expected bare fn in register_rust_fn_with_foreign_abi")
};
let llfn = base::register_fn_llvmty(ccx, sp, sym, node_id, cconv, llfn_ty);
add_argument_attributes(&tys, llfn);
debug!("register_rust_fn_with_foreign_abi(node_id={:?}, llfn_ty={}, llfn={})",
- node_id, ccx.tn.type_to_str(llfn_ty), ccx.tn.val_to_str(llfn));
+ node_id, ccx.tn.type_to_string(llfn_ty), ccx.tn.val_to_string(llfn));
llfn
}
let ps = ccx.tcx.map.with_path(id, |path| {
let abi = Some(ast_map::PathName(special_idents::clownshoe_abi.name));
- link::mangle(path.chain(abi.move_iter()), None, None)
+ link::mangle(path.chain(abi.move_iter()), None)
});
// Compute the type that the function would have if it were just a
_ => {
ccx.sess().bug(format!("build_rust_fn: extern fn {} has ty {}, \
expected a bare fn ty",
- ccx.tcx.map.path_to_str(id),
+ ccx.tcx.map.path_to_string(id),
t.repr(tcx)).as_slice());
}
};
debug!("build_rust_fn: path={} id={} t={}",
- ccx.tcx.map.path_to_str(id),
+ ccx.tcx.map.path_to_string(id),
id, t.repr(tcx));
let llfn = base::decl_internal_rust_fn(ccx, t, ps.as_slice());
let t = ty::node_id_to_type(tcx, id);
debug!("build_wrap_fn(llrustfn={}, llwrapfn={}, t={})",
- ccx.tn.val_to_str(llrustfn),
- ccx.tn.val_to_str(llwrapfn),
+ ccx.tn.val_to_string(llrustfn),
+ ccx.tn.val_to_string(llwrapfn),
t.repr(ccx.tcx()));
// Avoid all the Rust generation stuff and just generate raw
"the block".with_c_str(
|s| llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llwrapfn, s));
- let builder = ccx.builder.b;
- llvm::LLVMPositionBuilderAtEnd(builder, the_block);
+ let builder = ccx.builder();
+ builder.position_at_end(the_block);
// Array for the arguments we will pass to the rust function.
let mut llrust_args = Vec::new();
match foreign_outptr {
Some(llforeign_outptr) => {
debug!("out pointer, foreign={}",
- ccx.tn.val_to_str(llforeign_outptr));
+ ccx.tn.val_to_string(llforeign_outptr));
let llrust_retptr =
- llvm::LLVMBuildBitCast(builder,
- llforeign_outptr,
- llrust_ret_ty.ptr_to().to_ref(),
- noname());
+ builder.bitcast(llforeign_outptr, llrust_ret_ty.ptr_to());
debug!("out pointer, foreign={} (casted)",
- ccx.tn.val_to_str(llrust_retptr));
+ ccx.tn.val_to_string(llrust_retptr));
llrust_args.push(llrust_retptr);
return_alloca = None;
}
None => {
- let slot = {
- "return_alloca".with_c_str(
- |s| llvm::LLVMBuildAlloca(builder,
- llrust_ret_ty.to_ref(),
- s))
- };
+ let slot = builder.alloca(llrust_ret_ty, "return_alloca");
debug!("out pointer, \
allocad={}, \
llrust_ret_ty={}, \
return_ty={}",
- ccx.tn.val_to_str(slot),
- ccx.tn.type_to_str(llrust_ret_ty),
+ ccx.tn.val_to_string(slot),
+ ccx.tn.type_to_string(llrust_ret_ty),
tys.fn_sig.output.repr(tcx));
llrust_args.push(slot);
return_alloca = Some(slot);
let mut llforeign_arg = llvm::LLVMGetParam(llwrapfn, foreign_index);
debug!("llforeign_arg {}{}: {}", "#",
- i, ccx.tn.val_to_str(llforeign_arg));
+ i, ccx.tn.val_to_string(llforeign_arg));
debug!("rust_indirect = {}, foreign_indirect = {}",
rust_indirect, foreign_indirect);
// pointer). It makes adapting types easier, since we can
// always just bitcast pointers.
if !foreign_indirect {
- let lltemp =
- llvm::LLVMBuildAlloca(
- builder, val_ty(llforeign_arg).to_ref(), noname());
- llvm::LLVMBuildStore(
- builder, llforeign_arg, lltemp);
- llforeign_arg = lltemp;
+ llforeign_arg = if ty::type_is_bool(rust_ty) {
+ let lltemp = builder.alloca(Type::bool(ccx), "");
+ builder.store(builder.zext(llforeign_arg, Type::bool(ccx)), lltemp);
+ lltemp
+ } else {
+ let lltemp = builder.alloca(val_ty(llforeign_arg), "");
+ builder.store(llforeign_arg, lltemp);
+ lltemp
+ }
}
// If the types in the ABI and the Rust types don't match,
// Rust expects.
if llforeign_arg_ty.cast.is_some() {
assert!(!foreign_indirect);
- llforeign_arg = llvm::LLVMBuildBitCast(
- builder, llforeign_arg,
- llrust_ty.ptr_to().to_ref(), noname());
+ llforeign_arg = builder.bitcast(llforeign_arg, llrust_ty.ptr_to());
}
let llrust_arg = if rust_indirect {
llforeign_arg
} else {
- llvm::LLVMBuildLoad(builder, llforeign_arg, noname())
+ if ty::type_is_bool(rust_ty) {
+ let tmp = builder.load_range_assert(llforeign_arg, 0, 2, llvm::False);
+ builder.trunc(tmp, Type::i1(ccx))
+ } else {
+ builder.load(llforeign_arg)
+ }
};
debug!("llrust_arg {}{}: {}", "#",
- i, ccx.tn.val_to_str(llrust_arg));
+ i, ccx.tn.val_to_string(llrust_arg));
llrust_args.push(llrust_arg);
}
// Perform the call itself
- debug!("calling llrustfn = {}, t = {}", ccx.tn.val_to_str(llrustfn), t.repr(ccx.tcx()));
- let llrust_ret_val = llvm::LLVMBuildCall(builder, llrustfn, llrust_args.as_ptr(),
- llrust_args.len() as c_uint, noname());
-
+ debug!("calling llrustfn = {}, t = {}", ccx.tn.val_to_string(llrustfn), t.repr(ccx.tcx()));
let attributes = base::get_fn_llvm_attributes(ccx, t);
- for &(idx, attr) in attributes.iter() {
- llvm::LLVMAddCallSiteAttribute(llrust_ret_val, idx as c_uint, attr);
- }
+ let llrust_ret_val = builder.call(llrustfn, llrust_args.as_slice(), attributes.as_slice());
// Get the return value where the foreign fn expects it.
let llforeign_ret_ty = match tys.fn_ty.ret_ty.cast {
None if !tys.ret_def => {
// Function returns `()` or `bot`, which in Rust is the LLVM
// type "{}" but in foreign ABIs is "Void".
- llvm::LLVMBuildRetVoid(builder);
+ builder.ret_void();
}
None if rust_uses_outptr => {
// Rust uses an outpointer, but the foreign ABI does not. Load.
let llrust_outptr = return_alloca.unwrap();
let llforeign_outptr_casted =
- llvm::LLVMBuildBitCast(builder,
- llrust_outptr,
- llforeign_ret_ty.ptr_to().to_ref(),
- noname());
- let llforeign_retval =
- llvm::LLVMBuildLoad(builder, llforeign_outptr_casted, noname());
- llvm::LLVMBuildRet(builder, llforeign_retval);
+ builder.bitcast(llrust_outptr, llforeign_ret_ty.ptr_to());
+ let llforeign_retval = builder.load(llforeign_outptr_casted);
+ builder.ret(llforeign_retval);
}
None if llforeign_ret_ty != llrust_ret_ty => {
// right now we just use a temp memory location and
// bitcast the pointer, which is the same thing the
// old wrappers used to do.
- let lltemp =
- llvm::LLVMBuildAlloca(
- builder, llforeign_ret_ty.to_ref(), noname());
- let lltemp_casted =
- llvm::LLVMBuildBitCast(builder,
- lltemp,
- llrust_ret_ty.ptr_to().to_ref(),
- noname());
- llvm::LLVMBuildStore(
- builder, llrust_ret_val, lltemp_casted);
- let llforeign_retval =
- llvm::LLVMBuildLoad(builder, lltemp, noname());
- llvm::LLVMBuildRet(builder, llforeign_retval);
+ let lltemp = builder.alloca(llforeign_ret_ty, "");
+ let lltemp_casted = builder.bitcast(lltemp, llrust_ret_ty.ptr_to());
+ builder.store(llrust_ret_val, lltemp_casted);
+ let llforeign_retval = builder.load(lltemp);
+ builder.ret(llforeign_retval);
}
None => {
// Neither ABI uses an outpointer, and the types
// match. Easy peasy.
- llvm::LLVMBuildRet(builder, llrust_ret_val);
+ builder.ret(llrust_ret_val);
}
Some(llforeign_outptr) if !rust_uses_outptr => {
// Foreign ABI requires an out pointer, but Rust doesn't.
// Store Rust return value.
let llforeign_outptr_casted =
- llvm::LLVMBuildBitCast(builder,
- llforeign_outptr,
- llrust_retptr_ty.to_ref(),
- noname());
- llvm::LLVMBuildStore(
- builder, llrust_ret_val, llforeign_outptr_casted);
- llvm::LLVMBuildRetVoid(builder);
+ builder.bitcast(llforeign_outptr, llrust_retptr_ty);
+ builder.store(llrust_ret_val, llforeign_outptr_casted);
+ builder.ret_void();
}
Some(_) => {
// Both ABIs use outpointers. Easy peasy.
- llvm::LLVMBuildRetVoid(builder);
+ builder.ret_void();
}
}
}
* values by pointer like we do.
*/
- let llarg_tys = arg_tys.iter().map(|&arg| type_of(ccx, arg)).collect();
- let llret_ty = type_of::type_of(ccx, fn_sig.output);
+ let llarg_tys = arg_tys.iter().map(|&arg| arg_type_of(ccx, arg)).collect();
+ let llret_ty = type_of::arg_type_of(ccx, fn_sig.output);
LlvmSignature {
llarg_tys: llarg_tys,
llret_ty: llret_ty
ret_def={}",
ty.repr(ccx.tcx()),
ccx.tn.types_to_str(llsig.llarg_tys.as_slice()),
- ccx.tn.type_to_str(llsig.llret_ty),
+ ccx.tn.type_to_string(llsig.llret_ty),
ccx.tn.types_to_str(fn_ty.arg_tys.iter().map(|t| t.ty).collect::<Vec<_>>().as_slice()),
- ccx.tn.type_to_str(fn_ty.ret_ty.ty),
+ ccx.tn.type_to_string(fn_ty.ret_ty.ty),
ret_def);
ForeignTypes {
use back::abi;
use back::link::*;
-use lib::llvm::{llvm, ValueRef, True};
-use lib;
+use llvm;
+use llvm::{ValueRef, True};
use middle::lang_items::{FreeFnLangItem, ExchangeFreeFnLangItem};
use middle::subst;
use middle::trans::adt;
match ti.visit_glue.get() {
Some(visit_glue) => visit_glue,
None => {
- debug!("+++ lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_str(ccx.tcx(), ti.ty));
+ debug!("+++ lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_string(ccx.tcx(), ti.ty));
let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, "visit");
ti.visit_glue.set(Some(glue_fn));
make_generic_glue(ccx, ti.ty, glue_fn, make_visit_glue, "visit");
- debug!("--- lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_str(ccx.tcx(), ti.ty));
+ debug!("--- lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_string(ccx.tcx(), ti.ty));
glue_fn
}
}
-> &'a Block<'a> {
let repr = adt::represent_type(bcx.ccx(), t);
let drop_flag = adt::trans_drop_flag_ptr(bcx, &*repr, v0);
- with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag)), |cx| {
+ with_cond(bcx, load_ty(bcx, drop_flag, ty::mk_bool()), |cx| {
trans_struct_drop(cx, t, v0, dtor_did, class_did, substs)
})
}
if ccx.sess().count_type_sizes() {
println!("{}\t{}", llsize_of_real(ccx, llty),
- ppaux::ty_to_str(ccx.tcx(), t));
+ ppaux::ty_to_string(ccx.tcx(), t));
}
let llsize = llsize_of(ccx, llty);
let llalign = llalign_of(ccx, llty);
let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc");
- debug!("+++ declare_tydesc {} {}", ppaux::ty_to_str(ccx.tcx(), t), name);
+ debug!("+++ declare_tydesc {} {}", ppaux::ty_to_string(ccx.tcx(), t), name);
let gvar = name.as_slice().with_c_str(|buf| {
unsafe {
llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type().to_ref(), buf)
note_unique_llvm_symbol(ccx, name);
let ty_name = token::intern_and_get_ident(
- ppaux::ty_to_str(ccx.tcx(), t).as_slice());
+ ppaux::ty_to_string(ccx.tcx(), t).as_slice());
let ty_name = C_str_slice(ccx, ty_name);
- debug!("--- declare_tydesc {}", ppaux::ty_to_str(ccx.tcx(), t));
+ debug!("--- declare_tydesc {}", ppaux::ty_to_string(ccx.tcx(), t));
tydesc_info {
ty: t,
tydesc: gvar,
ccx,
t,
format!("glue_{}", name).as_slice());
- debug!("{} is for type {}", fn_nm, ppaux::ty_to_str(ccx.tcx(), t));
+ debug!("{} is for type {}", fn_nm, ppaux::ty_to_string(ccx.tcx(), t));
let llfn = decl_cdecl_fn(ccx, fn_nm.as_slice(), llfnty, ty::mk_nil());
note_unique_llvm_symbol(ccx, fn_nm);
return llfn;
let fcx = new_fn_ctxt(ccx, llfn, -1, false, ty::mk_nil(),
&empty_param_substs, None, &arena);
- init_function(&fcx, false, ty::mk_nil());
+ let bcx = init_function(&fcx, false, ty::mk_nil());
- lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
+ llvm::SetLinkage(llfn, llvm::InternalLinkage);
ccx.stats.n_glues_created.set(ccx.stats.n_glues_created.get() + 1u);
// All glue functions take values passed *by alias*; this is a
// requirement since in many contexts glue is invoked indirectly and
// llfn is expected be declared to take a parameter of the appropriate
// type, so we don't need to explicitly cast the function parameter.
- let bcx = fcx.entry_bcx.borrow().clone().unwrap();
let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, fcx.arg_pos(0) as c_uint) };
let bcx = helper(bcx, llrawptr0, t);
- finish_fn(&fcx, bcx);
+ finish_fn(&fcx, bcx, ty::mk_nil());
llfn
}
let gvar = ti.tydesc;
llvm::LLVMSetInitializer(gvar, tydesc);
llvm::LLVMSetGlobalConstant(gvar, True);
- lib::llvm::SetLinkage(gvar, lib::llvm::InternalLinkage);
+ llvm::SetLinkage(gvar, llvm::InternalLinkage);
}
};
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use lib::llvm::{AvailableExternallyLinkage, SetLinkage};
+use llvm::{AvailableExternallyLinkage, SetLinkage};
use metadata::csearch;
use middle::astencode;
use middle::trans::base::{push_ctxt, trans_item, get_item_val, trans_fn};
let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
let unparameterized =
impl_tpt.generics.types.is_empty() &&
- mth.generics.ty_params.is_empty();
+ ast_util::method_generics(&*mth).ty_params.is_empty();
if unparameterized {
let llfn = get_item_val(ccx, mth.id);
- trans_fn(ccx, &*mth.decl, &*mth.body, llfn,
+ trans_fn(ccx, ast_util::method_fn_decl(&*mth),
+ ast_util::method_body(&*mth), llfn,
¶m_substs::empty(), mth.id, []);
}
local_def(mth.id)
#![allow(non_uppercase_pattern_statics)]
-use arena::TypedArena;
-use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg};
-use lib::llvm::{ValueRef, Pointer, Array, Struct};
-use lib;
+use llvm;
+use llvm::{SequentiallyConsistent, Acquire, Release, Xchg, ValueRef};
+use middle::subst;
use middle::subst::FnSpace;
use middle::trans::base::*;
use middle::trans::build::*;
+use middle::trans::callee;
+use middle::trans::cleanup;
+use middle::trans::cleanup::CleanupMethods;
use middle::trans::common::*;
use middle::trans::datum::*;
+use middle::trans::expr;
use middle::trans::glue;
use middle::trans::type_of::*;
use middle::trans::type_of;
use middle::trans::type_::Type;
use middle::ty;
use syntax::ast;
-use syntax::ast_map;
use syntax::parse::token;
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
pub fn get_simple_intrinsic(ccx: &CrateContext, item: &ast::ForeignItem) -> Option<ValueRef> {
let name = match token::get_ident(item.ident).get() {
Some(ccx.get_intrinsic(&name))
}
-pub fn trans_intrinsic(ccx: &CrateContext,
- decl: ValueRef,
- item: &ast::ForeignItem,
- substs: ¶m_substs,
- ref_id: Option<ast::NodeId>) {
- debug!("trans_intrinsic(item.ident={})", token::get_ident(item.ident));
-
- fn with_overflow_instrinsic(bcx: &Block, name: &'static str, t: ty::t) {
- let first_real_arg = bcx.fcx.arg_pos(0u);
- let a = get_param(bcx.fcx.llfn, first_real_arg);
- let b = get_param(bcx.fcx.llfn, first_real_arg + 1);
- let llfn = bcx.ccx().get_intrinsic(&name);
-
- let val = Call(bcx, llfn, [a, b], []);
-
- if type_is_immediate(bcx.ccx(), t) {
- Ret(bcx, val);
- } else {
- let retptr = get_param(bcx.fcx.llfn, bcx.fcx.out_arg_pos());
- Store(bcx, val, retptr);
- RetVoid(bcx);
+/// Performs late verification that intrinsics are used correctly. At present,
+/// the only intrinsic that needs such verification is `transmute`.
+pub fn check_intrinsics(ccx: &CrateContext) {
+ for transmute_restriction in ccx.tcx
+ .transmute_restrictions
+ .borrow()
+ .iter() {
+ let llfromtype = type_of::sizing_type_of(ccx,
+ transmute_restriction.from);
+ let lltotype = type_of::sizing_type_of(ccx,
+ transmute_restriction.to);
+ let from_type_size = machine::llbitsize_of_real(ccx, llfromtype);
+ let to_type_size = machine::llbitsize_of_real(ccx, lltotype);
+ if from_type_size != to_type_size {
+ ccx.sess()
+ .span_err(transmute_restriction.span,
+ format!("transmute called on types with different sizes: \
+ {} ({} bit{}) to {} ({} bit{})",
+ ty_to_string(ccx.tcx(), transmute_restriction.from),
+ from_type_size as uint,
+ if from_type_size == 1 {
+ ""
+ } else {
+ "s"
+ },
+ ty_to_string(ccx.tcx(), transmute_restriction.to),
+ to_type_size as uint,
+ if to_type_size == 1 {
+ ""
+ } else {
+ "s"
+ }).as_slice());
}
}
+ ccx.sess().abort_if_errors();
+}
- fn volatile_load_intrinsic(bcx: &Block) {
- let first_real_arg = bcx.fcx.arg_pos(0u);
- let src = get_param(bcx.fcx.llfn, first_real_arg);
+pub fn trans_intrinsic_call<'a>(mut bcx: &'a Block<'a>, node: ast::NodeId,
+ callee_ty: ty::t, cleanup_scope: cleanup::CustomScopeIndex,
+ args: callee::CallArgs, dest: expr::Dest,
+ substs: subst::Substs) -> Result<'a> {
- let val = VolatileLoad(bcx, src);
- Ret(bcx, val);
- }
+ let fcx = bcx.fcx;
+ let ccx = fcx.ccx;
+ let tcx = bcx.tcx();
- fn volatile_store_intrinsic(bcx: &Block) {
- let first_real_arg = bcx.fcx.arg_pos(0u);
- let dst = get_param(bcx.fcx.llfn, first_real_arg);
- let val = get_param(bcx.fcx.llfn, first_real_arg + 1);
+ let ret_ty = match ty::get(callee_ty).sty {
+ ty::ty_bare_fn(ref f) => f.sig.output,
+ _ => fail!("expected bare_fn in trans_intrinsic_call")
+ };
+ let llret_ty = type_of::type_of(ccx, ret_ty);
+ let foreign_item = tcx.map.expect_foreign_item(node);
+ let name = token::get_ident(foreign_item.ident);
+
+ // For `transmute` we can just trans the input expr directly into dest
+ if name.get() == "transmute" {
+ match args {
+ callee::ArgExprs(arg_exprs) => {
+ assert_eq!(arg_exprs.len(), 1);
+
+ let (in_type, out_type) = (*substs.types.get(FnSpace, 0),
+ *substs.types.get(FnSpace, 1));
+ let llintype = type_of::type_of(ccx, in_type);
+ let llouttype = type_of::type_of(ccx, out_type);
+
+ let in_type_size = machine::llbitsize_of_real(ccx, llintype);
+ let out_type_size = machine::llbitsize_of_real(ccx, llouttype);
+
+ // This should be caught by the intrinsicck pass
+ assert_eq!(in_type_size, out_type_size);
+
+ // We need to cast the dest so the types work out
+ let dest = match dest {
+ expr::SaveIn(d) => expr::SaveIn(PointerCast(bcx, d, llintype.ptr_to())),
+ expr::Ignore => expr::Ignore
+ };
+ bcx = expr::trans_into(bcx, &*arg_exprs[0], dest);
- VolatileStore(bcx, val, dst);
- RetVoid(bcx);
- }
+ fcx.pop_custom_cleanup_scope(cleanup_scope);
- fn copy_intrinsic(bcx: &Block, allow_overlap: bool, volatile: bool, tp_ty: ty::t) {
- let ccx = bcx.ccx();
- let lltp_ty = type_of::type_of(ccx, tp_ty);
- let align = C_i32(ccx, machine::llalign_of_min(ccx, lltp_ty) as i32);
- let size = machine::llsize_of(ccx, lltp_ty);
- let int_size = machine::llbitsize_of_real(ccx, ccx.int_type);
- let name = if allow_overlap {
- if int_size == 32 {
- "llvm.memmove.p0i8.p0i8.i32"
- } else {
- "llvm.memmove.p0i8.p0i8.i64"
- }
- } else {
- if int_size == 32 {
- "llvm.memcpy.p0i8.p0i8.i32"
- } else {
- "llvm.memcpy.p0i8.p0i8.i64"
- }
- };
-
- let decl = bcx.fcx.llfn;
- let first_real_arg = bcx.fcx.arg_pos(0u);
- let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p(ccx));
- let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p(ccx));
- let count = get_param(decl, first_real_arg + 2);
- let llfn = ccx.get_intrinsic(&name);
- Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, C_i1(ccx, volatile)], []);
- RetVoid(bcx);
- }
+ return match dest {
+ expr::SaveIn(d) => Result::new(bcx, d),
+ expr::Ignore => Result::new(bcx, C_undef(llret_ty.ptr_to()))
+ };
- fn memset_intrinsic(bcx: &Block, volatile: bool, tp_ty: ty::t) {
- let ccx = bcx.ccx();
- let lltp_ty = type_of::type_of(ccx, tp_ty);
- let align = C_i32(ccx, machine::llalign_of_min(ccx, lltp_ty) as i32);
- let size = machine::llsize_of(ccx, lltp_ty);
- let name = if machine::llbitsize_of_real(ccx, ccx.int_type) == 32 {
- "llvm.memset.p0i8.i32"
- } else {
- "llvm.memset.p0i8.i64"
- };
-
- let decl = bcx.fcx.llfn;
- let first_real_arg = bcx.fcx.arg_pos(0u);
- let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p(ccx));
- let val = get_param(decl, first_real_arg + 1);
- let count = get_param(decl, first_real_arg + 2);
- let llfn = ccx.get_intrinsic(&name);
- Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, C_i1(ccx, volatile)], []);
- RetVoid(bcx);
- }
+ }
- fn count_zeros_intrinsic(bcx: &Block, name: &'static str) {
- let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u));
- let y = C_i1(bcx.ccx(), false);
- let llfn = bcx.ccx().get_intrinsic(&name);
- let llcall = Call(bcx, llfn, [x, y], []);
- Ret(bcx, llcall);
+ _ => {
+ ccx.sess().bug("expected expr as argument for transmute");
+ }
+ }
}
- let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx(), item.id));
-
- let arena = TypedArena::new();
- let fcx = new_fn_ctxt(ccx, decl, item.id, false, output_type,
- substs, Some(item.span), &arena);
- init_function(&fcx, true, output_type);
-
- set_always_inline(fcx.llfn);
+ // Get location to store the result. If the user does
+ // not care about the result, just make a stack slot
+ let llresult = match dest {
+ expr::SaveIn(d) => d,
+ expr::Ignore => {
+ if !type_is_zero_size(ccx, ret_ty) {
+ alloc_ty(bcx, ret_ty, "intrinsic_result")
+ } else {
+ C_undef(llret_ty.ptr_to())
+ }
+ }
+ };
- let mut bcx = fcx.entry_bcx.borrow().clone().unwrap();
- let first_real_arg = fcx.arg_pos(0u);
+ // Push the arguments.
+ let mut llargs = Vec::new();
+ bcx = callee::trans_args(bcx, args, callee_ty, &mut llargs,
+ cleanup::CustomScope(cleanup_scope), false);
- let name = token::get_ident(item.ident);
+ fcx.pop_custom_cleanup_scope(cleanup_scope);
- // This requires that atomic intrinsics follow a specific naming pattern:
- // "atomic_<operation>[_<ordering>], and no ordering means SeqCst
- if name.get().starts_with("atomic_") {
- let split: Vec<&str> = name.get().split('_').collect();
- assert!(split.len() >= 2, "Atomic intrinsic not correct format");
- let order = if split.len() == 2 {
- lib::llvm::SequentiallyConsistent
- } else {
- match *split.get(2) {
- "relaxed" => lib::llvm::Monotonic,
- "acq" => lib::llvm::Acquire,
- "rel" => lib::llvm::Release,
- "acqrel" => lib::llvm::AcquireRelease,
- _ => ccx.sess().fatal("unknown ordering in atomic intrinsic")
- }
- };
-
- match *split.get(1) {
- "cxchg" => {
- // See include/llvm/IR/Instructions.h for their implementation
- // of this, I assume that it's good enough for us to use for
- // now.
- let strongest_failure_ordering = match order {
- lib::llvm::NotAtomic | lib::llvm::Unordered =>
- ccx.sess().fatal("cmpxchg must be atomic"),
- lib::llvm::Monotonic | lib::llvm::Release =>
- lib::llvm::Monotonic,
- lib::llvm::Acquire | lib::llvm::AcquireRelease =>
- lib::llvm::Acquire,
- lib::llvm::SequentiallyConsistent =>
- lib::llvm::SequentiallyConsistent,
- };
- let res = AtomicCmpXchg(bcx, get_param(decl, first_real_arg),
- get_param(decl, first_real_arg + 1u),
- get_param(decl, first_real_arg + 2u),
- order, strongest_failure_ordering);
- if unsafe { lib::llvm::llvm::LLVMVersionMinor() >= 5 } {
- Ret(bcx, ExtractValue(bcx, res, 0));
- } else {
- Ret(bcx, res);
- }
- }
- "load" => {
- let old = AtomicLoad(bcx, get_param(decl, first_real_arg),
- order);
- Ret(bcx, old);
- }
- "store" => {
- AtomicStore(bcx, get_param(decl, first_real_arg + 1u),
- get_param(decl, first_real_arg),
- order);
- RetVoid(bcx);
- }
- "fence" => {
- AtomicFence(bcx, order);
- RetVoid(bcx);
- }
- op => {
- // These are all AtomicRMW ops
- let atom_op = match op {
- "xchg" => lib::llvm::Xchg,
- "xadd" => lib::llvm::Add,
- "xsub" => lib::llvm::Sub,
- "and" => lib::llvm::And,
- "nand" => lib::llvm::Nand,
- "or" => lib::llvm::Or,
- "xor" => lib::llvm::Xor,
- "max" => lib::llvm::Max,
- "min" => lib::llvm::Min,
- "umax" => lib::llvm::UMax,
- "umin" => lib::llvm::UMin,
- _ => ccx.sess().fatal("unknown atomic operation")
- };
+ let simple = get_simple_intrinsic(ccx, &*foreign_item);
- let old = AtomicRMW(bcx, atom_op, get_param(decl, first_real_arg),
- get_param(decl, first_real_arg + 1u),
- order);
- Ret(bcx, old);
- }
+ let llval = match (simple, name.get()) {
+ (Some(llfn), _) => {
+ Call(bcx, llfn, llargs.as_slice(), [])
}
-
- fcx.cleanup();
- return;
- }
-
- match name.get() {
- "abort" => {
- let llfn = bcx.ccx().get_intrinsic(&("llvm.trap"));
- Call(bcx, llfn, [], []);
+ (_, "abort") => {
+ let llfn = ccx.get_intrinsic(&("llvm.trap"));
+ let v = Call(bcx, llfn, [], []);
Unreachable(bcx);
+ v
+ }
+ (_, "breakpoint") => {
+ let llfn = ccx.get_intrinsic(&("llvm.debugtrap"));
+ Call(bcx, llfn, [], [])
}
- "breakpoint" => {
- let llfn = bcx.ccx().get_intrinsic(&("llvm.debugtrap"));
- Call(bcx, llfn, [], []);
- RetVoid(bcx);
+ (_, "size_of") => {
+ let tp_ty = *substs.types.get(FnSpace, 0);
+ let lltp_ty = type_of::type_of(ccx, tp_ty);
+ C_uint(ccx, machine::llsize_of_real(ccx, lltp_ty) as uint)
+ }
+ (_, "min_align_of") => {
+ let tp_ty = *substs.types.get(FnSpace, 0);
+ let lltp_ty = type_of::type_of(ccx, tp_ty);
+ C_uint(ccx, machine::llalign_of_min(ccx, lltp_ty) as uint)
}
- "size_of" => {
- let tp_ty = *substs.substs.types.get(FnSpace, 0);
+ (_, "pref_align_of") => {
+ let tp_ty = *substs.types.get(FnSpace, 0);
let lltp_ty = type_of::type_of(ccx, tp_ty);
- Ret(bcx, C_uint(ccx, machine::llsize_of_real(ccx, lltp_ty) as uint));
+ C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty) as uint)
}
- "move_val_init" => {
+ (_, "move_val_init") => {
// Create a datum reflecting the value being moved.
// Use `appropriate_mode` so that the datum is by ref
// if the value is non-immediate. Note that, with
// intrinsics, there are no argument cleanups to
// concern ourselves with, so we can use an rvalue datum.
- let tp_ty = *substs.substs.types.get(FnSpace, 0);
+ let tp_ty = *substs.types.get(FnSpace, 0);
let mode = appropriate_rvalue_mode(ccx, tp_ty);
- let src = Datum {val: get_param(decl, first_real_arg + 1u),
- ty: tp_ty,
- kind: Rvalue::new(mode)};
- bcx = src.store_to(bcx, get_param(decl, first_real_arg));
- RetVoid(bcx);
+ let src = Datum {
+ val: *llargs.get(1),
+ ty: tp_ty,
+ kind: Rvalue::new(mode)
+ };
+ bcx = src.store_to(bcx, *llargs.get(0));
+ C_nil(ccx)
}
- "min_align_of" => {
- let tp_ty = *substs.substs.types.get(FnSpace, 0);
- let lltp_ty = type_of::type_of(ccx, tp_ty);
- Ret(bcx, C_uint(ccx, machine::llalign_of_min(ccx, lltp_ty) as uint));
- }
- "pref_align_of"=> {
- let tp_ty = *substs.substs.types.get(FnSpace, 0);
- let lltp_ty = type_of::type_of(ccx, tp_ty);
- Ret(bcx, C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty) as uint));
- }
- "get_tydesc" => {
- let tp_ty = *substs.substs.types.get(FnSpace, 0);
+ (_, "get_tydesc") => {
+ let tp_ty = *substs.types.get(FnSpace, 0);
let static_ti = get_tydesc(ccx, tp_ty);
glue::lazily_emit_visit_glue(ccx, &*static_ti);
// but there's a circularity between translating rust types to llvm
// types and having a tydesc type available. So I can't directly access
// the llvm type of intrinsic::TyDesc struct.
- let userland_tydesc_ty = type_of::type_of(ccx, output_type);
- let td = PointerCast(bcx, static_ti.tydesc, userland_tydesc_ty);
- Ret(bcx, td);
+ PointerCast(bcx, static_ti.tydesc, llret_ty)
}
- "type_id" => {
+ (_, "type_id") => {
let hash = ty::hash_crate_independent(
ccx.tcx(),
- *substs.substs.types.get(FnSpace, 0),
+ *substs.types.get(FnSpace, 0),
&ccx.link_meta.crate_hash);
// NB: This needs to be kept in lockstep with the TypeId struct in
- // libstd/unstable/intrinsics.rs
- let val = C_named_struct(type_of::type_of(ccx, output_type),
- [C_u64(ccx, hash)]);
- match bcx.fcx.llretptr.get() {
- Some(ptr) => {
- Store(bcx, val, ptr);
- RetVoid(bcx);
- },
- None => Ret(bcx, val)
- }
+ // the intrinsic module
+ C_named_struct(llret_ty, [C_u64(ccx, hash)])
}
- "init" => {
- let tp_ty = *substs.substs.types.get(FnSpace, 0);
+ (_, "init") => {
+ let tp_ty = *substs.types.get(FnSpace, 0);
let lltp_ty = type_of::type_of(ccx, tp_ty);
- match bcx.fcx.llretptr.get() {
- Some(ptr) => { Store(bcx, C_null(lltp_ty), ptr); RetVoid(bcx); }
- None if ty::type_is_nil(tp_ty) => RetVoid(bcx),
- None => Ret(bcx, C_null(lltp_ty)),
- }
- }
- "uninit" => {
- // Do nothing, this is effectively a no-op
- let retty = *substs.substs.types.get(FnSpace, 0);
- if type_is_immediate(ccx, retty) && !return_type_is_void(ccx, retty) {
- unsafe {
- Ret(bcx, lib::llvm::llvm::LLVMGetUndef(type_of(ccx, retty).to_ref()));
- }
+ if return_type_is_void(ccx, tp_ty) {
+ C_nil(ccx)
} else {
- RetVoid(bcx)
+ C_null(lltp_ty)
}
}
- "forget" => {
- RetVoid(bcx);
- }
- "transmute" => {
- let (in_type, out_type) = (*substs.substs.types.get(FnSpace, 0),
- *substs.substs.types.get(FnSpace, 1));
- let llintype = type_of::type_of(ccx, in_type);
- let llouttype = type_of::type_of(ccx, out_type);
-
- let in_type_size = machine::llbitsize_of_real(ccx, llintype);
- let out_type_size = machine::llbitsize_of_real(ccx, llouttype);
- if in_type_size != out_type_size {
- let sp = match ccx.tcx.map.get(ref_id.unwrap()) {
- ast_map::NodeExpr(e) => e.span,
- _ => fail!("transmute has non-expr arg"),
- };
- ccx.sess().span_bug(sp,
- format!("transmute called on types with different sizes: \
- {} ({} bit{}) to \
- {} ({} bit{})",
- ty_to_str(ccx.tcx(), in_type),
- in_type_size,
- if in_type_size == 1 {""} else {"s"},
- ty_to_str(ccx.tcx(), out_type),
- out_type_size,
- if out_type_size == 1 {""} else {"s"}).as_slice());
- }
-
- if !return_type_is_void(ccx, out_type) {
- let llsrcval = get_param(decl, first_real_arg);
- if type_is_immediate(ccx, in_type) {
- match fcx.llretptr.get() {
- Some(llretptr) => {
- Store(bcx, llsrcval, PointerCast(bcx, llretptr, llintype.ptr_to()));
- RetVoid(bcx);
- }
- None => match (llintype.kind(), llouttype.kind()) {
- (Pointer, other) | (other, Pointer) if other != Pointer => {
- let tmp = Alloca(bcx, llouttype, "");
- Store(bcx, llsrcval, PointerCast(bcx, tmp, llintype.ptr_to()));
- Ret(bcx, Load(bcx, tmp));
- }
- (Array, _) | (_, Array) | (Struct, _) | (_, Struct) => {
- let tmp = Alloca(bcx, llouttype, "");
- Store(bcx, llsrcval, PointerCast(bcx, tmp, llintype.ptr_to()));
- Ret(bcx, Load(bcx, tmp));
- }
- _ => {
- let llbitcast = BitCast(bcx, llsrcval, llouttype);
- Ret(bcx, llbitcast)
- }
- }
- }
- } else if type_is_immediate(ccx, out_type) {
- let llsrcptr = PointerCast(bcx, llsrcval, llouttype.ptr_to());
- let ll_load = Load(bcx, llsrcptr);
- Ret(bcx, ll_load);
- } else {
- // NB: Do not use a Load and Store here. This causes massive
- // code bloat when `transmute` is used on large structural
- // types.
- let lldestptr = fcx.llretptr.get().unwrap();
- let lldestptr = PointerCast(bcx, lldestptr, Type::i8p(ccx));
- let llsrcptr = PointerCast(bcx, llsrcval, Type::i8p(ccx));
-
- let llsize = llsize_of(ccx, llintype);
- call_memcpy(bcx, lldestptr, llsrcptr, llsize, 1);
- RetVoid(bcx);
- };
- } else {
- RetVoid(bcx);
- }
+ // Effectively no-ops
+ (_, "uninit") | (_, "forget") => {
+ C_nil(ccx)
}
- "needs_drop" => {
- let tp_ty = *substs.substs.types.get(FnSpace, 0);
- Ret(bcx, C_bool(ccx, ty::type_needs_drop(ccx.tcx(), tp_ty)));
+ (_, "needs_drop") => {
+ let tp_ty = *substs.types.get(FnSpace, 0);
+ C_bool(ccx, ty::type_needs_drop(ccx.tcx(), tp_ty))
}
- "owns_managed" => {
- let tp_ty = *substs.substs.types.get(FnSpace, 0);
- Ret(bcx, C_bool(ccx, ty::type_contents(ccx.tcx(), tp_ty).owns_managed()));
+ (_, "owns_managed") => {
+ let tp_ty = *substs.types.get(FnSpace, 0);
+ C_bool(ccx, ty::type_contents(ccx.tcx(), tp_ty).owns_managed())
}
- "visit_tydesc" => {
- let td = get_param(decl, first_real_arg);
- let visitor = get_param(decl, first_real_arg + 1u);
+ (_, "visit_tydesc") => {
+ let td = *llargs.get(0);
+ let visitor = *llargs.get(1);
let td = PointerCast(bcx, td, ccx.tydesc_type().ptr_to());
glue::call_visit_glue(bcx, visitor, td, None);
- RetVoid(bcx);
+ C_nil(ccx)
}
- "offset" => {
- let ptr = get_param(decl, first_real_arg);
- let offset = get_param(decl, first_real_arg + 1);
- let lladdr = InBoundsGEP(bcx, ptr, [offset]);
- Ret(bcx, lladdr);
+ (_, "offset") => {
+ let ptr = *llargs.get(0);
+ let offset = *llargs.get(1);
+ InBoundsGEP(bcx, ptr, [offset])
}
- "copy_nonoverlapping_memory" => {
- copy_intrinsic(bcx, false, false, *substs.substs.types.get(FnSpace, 0))
+
+ (_, "copy_nonoverlapping_memory") => {
+ copy_intrinsic(bcx, false, false, *substs.types.get(FnSpace, 0),
+ *llargs.get(0), *llargs.get(1), *llargs.get(2))
}
- "copy_memory" => {
- copy_intrinsic(bcx, true, false, *substs.substs.types.get(FnSpace, 0))
+ (_, "copy_memory") => {
+ copy_intrinsic(bcx, true, false, *substs.types.get(FnSpace, 0),
+ *llargs.get(0), *llargs.get(1), *llargs.get(2))
}
- "set_memory" => {
- memset_intrinsic(bcx, false, *substs.substs.types.get(FnSpace, 0))
+ (_, "set_memory") => {
+ memset_intrinsic(bcx, false, *substs.types.get(FnSpace, 0),
+ *llargs.get(0), *llargs.get(1), *llargs.get(2))
}
- "volatile_copy_nonoverlapping_memory" => {
- copy_intrinsic(bcx, false, true, *substs.substs.types.get(FnSpace, 0))
+ (_, "volatile_copy_nonoverlapping_memory") => {
+ copy_intrinsic(bcx, false, true, *substs.types.get(FnSpace, 0),
+ *llargs.get(0), *llargs.get(1), *llargs.get(2))
}
-
- "volatile_copy_memory" => {
- copy_intrinsic(bcx, true, true, *substs.substs.types.get(FnSpace, 0))
+ (_, "volatile_copy_memory") => {
+ copy_intrinsic(bcx, true, true, *substs.types.get(FnSpace, 0),
+ *llargs.get(0), *llargs.get(1), *llargs.get(2))
}
+ (_, "volatile_set_memory") => {
+ memset_intrinsic(bcx, true, *substs.types.get(FnSpace, 0),
+ *llargs.get(0), *llargs.get(1), *llargs.get(2))
+ }
+ (_, "volatile_load") => {
+ VolatileLoad(bcx, *llargs.get(0))
+ },
+ (_, "volatile_store") => {
+ VolatileStore(bcx, *llargs.get(1), *llargs.get(0));
+ C_nil(ccx)
+ },
+
+ (_, "ctlz8") => count_zeros_intrinsic(bcx, "llvm.ctlz.i8", *llargs.get(0)),
+ (_, "ctlz16") => count_zeros_intrinsic(bcx, "llvm.ctlz.i16", *llargs.get(0)),
+ (_, "ctlz32") => count_zeros_intrinsic(bcx, "llvm.ctlz.i32", *llargs.get(0)),
+ (_, "ctlz64") => count_zeros_intrinsic(bcx, "llvm.ctlz.i64", *llargs.get(0)),
+ (_, "cttz8") => count_zeros_intrinsic(bcx, "llvm.cttz.i8", *llargs.get(0)),
+ (_, "cttz16") => count_zeros_intrinsic(bcx, "llvm.cttz.i16", *llargs.get(0)),
+ (_, "cttz32") => count_zeros_intrinsic(bcx, "llvm.cttz.i32", *llargs.get(0)),
+ (_, "cttz64") => count_zeros_intrinsic(bcx, "llvm.cttz.i64", *llargs.get(0)),
+
+ (_, "i8_add_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.sadd.with.overflow.i8", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "i16_add_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.sadd.with.overflow.i16", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "i32_add_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.sadd.with.overflow.i32", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "i64_add_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.sadd.with.overflow.i64", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+
+ (_, "u8_add_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.uadd.with.overflow.i8", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "u16_add_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.uadd.with.overflow.i16", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "u32_add_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.uadd.with.overflow.i32", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "u64_add_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.uadd.with.overflow.i64", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+
+ (_, "i8_sub_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.ssub.with.overflow.i8", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "i16_sub_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.ssub.with.overflow.i16", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "i32_sub_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.ssub.with.overflow.i32", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "i64_sub_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.ssub.with.overflow.i64", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+
+ (_, "u8_sub_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.usub.with.overflow.i8", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "u16_sub_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.usub.with.overflow.i16", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "u32_sub_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.usub.with.overflow.i32", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "u64_sub_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.usub.with.overflow.i64", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+
+ (_, "i8_mul_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.smul.with.overflow.i8", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "i16_mul_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.smul.with.overflow.i16", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "i32_mul_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.smul.with.overflow.i32", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "i64_mul_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.smul.with.overflow.i64", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+
+ (_, "u8_mul_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i8", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "u16_mul_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i16", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "u32_mul_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i32", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+ (_, "u64_mul_with_overflow") =>
+ with_overflow_intrinsic(bcx, "llvm.umul.with.overflow.i64", ret_ty,
+ *llargs.get(0), *llargs.get(1)),
+
+ // This requires that atomic intrinsics follow a specific naming pattern:
+ // "atomic_<operation>[_<ordering>]", and no ordering means SeqCst
+ (_, name) if name.starts_with("atomic_") => {
+ let split: Vec<&str> = name.split('_').collect();
+ assert!(split.len() >= 2, "Atomic intrinsic not correct format");
+
+ let order = if split.len() == 2 {
+ llvm::SequentiallyConsistent
+ } else {
+ match *split.get(2) {
+ "relaxed" => llvm::Monotonic,
+ "acq" => llvm::Acquire,
+ "rel" => llvm::Release,
+ "acqrel" => llvm::AcquireRelease,
+ _ => ccx.sess().fatal("unknown ordering in atomic intrinsic")
+ }
+ };
+
+ match *split.get(1) {
+ "cxchg" => {
+ // See include/llvm/IR/Instructions.h for their implementation
+ // of this, I assume that it's good enough for us to use for
+ // now.
+ let strongest_failure_ordering = match order {
+ llvm::NotAtomic | llvm::Unordered =>
+ ccx.sess().fatal("cmpxchg must be atomic"),
+
+ llvm::Monotonic | llvm::Release =>
+ llvm::Monotonic,
+
+ llvm::Acquire | llvm::AcquireRelease =>
+ llvm::Acquire,
+
+ llvm::SequentiallyConsistent =>
+ llvm::SequentiallyConsistent
+ };
+
+ let res = AtomicCmpXchg(bcx, *llargs.get(0), *llargs.get(1),
+ *llargs.get(2), order,
+ strongest_failure_ordering);
+ if unsafe { llvm::LLVMVersionMinor() >= 5 } {
+ ExtractValue(bcx, res, 0)
+ } else {
+ res
+ }
+ }
+
+ "load" => {
+ AtomicLoad(bcx, *llargs.get(0), order)
+ }
+ "store" => {
+ AtomicStore(bcx, *llargs.get(1), *llargs.get(0), order);
+ C_nil(ccx)
+ }
+
+ "fence" => {
+ AtomicFence(bcx, order);
+ C_nil(ccx)
+ }
+
+ // These are all AtomicRMW ops
+ op => {
+ let atom_op = match op {
+ "xchg" => llvm::Xchg,
+ "xadd" => llvm::Add,
+ "xsub" => llvm::Sub,
+ "and" => llvm::And,
+ "nand" => llvm::Nand,
+ "or" => llvm::Or,
+ "xor" => llvm::Xor,
+ "max" => llvm::Max,
+ "min" => llvm::Min,
+ "umax" => llvm::UMax,
+ "umin" => llvm::UMin,
+ _ => ccx.sess().fatal("unknown atomic operation")
+ };
+
+ AtomicRMW(bcx, atom_op, *llargs.get(0), *llargs.get(1), order)
+ }
+ }
- "volatile_set_memory" => {
- memset_intrinsic(bcx, true, *substs.substs.types.get(FnSpace, 0))
}
- "ctlz8" => count_zeros_intrinsic(bcx, "llvm.ctlz.i8"),
- "ctlz16" => count_zeros_intrinsic(bcx, "llvm.ctlz.i16"),
- "ctlz32" => count_zeros_intrinsic(bcx, "llvm.ctlz.i32"),
- "ctlz64" => count_zeros_intrinsic(bcx, "llvm.ctlz.i64"),
- "cttz8" => count_zeros_intrinsic(bcx, "llvm.cttz.i8"),
- "cttz16" => count_zeros_intrinsic(bcx, "llvm.cttz.i16"),
- "cttz32" => count_zeros_intrinsic(bcx, "llvm.cttz.i32"),
- "cttz64" => count_zeros_intrinsic(bcx, "llvm.cttz.i64"),
-
- "volatile_load" => volatile_load_intrinsic(bcx),
- "volatile_store" => volatile_store_intrinsic(bcx),
-
- "i8_add_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.sadd.with.overflow.i8", output_type),
- "i16_add_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.sadd.with.overflow.i16", output_type),
- "i32_add_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.sadd.with.overflow.i32", output_type),
- "i64_add_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.sadd.with.overflow.i64", output_type),
-
- "u8_add_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.uadd.with.overflow.i8", output_type),
- "u16_add_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.uadd.with.overflow.i16", output_type),
- "u32_add_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.uadd.with.overflow.i32", output_type),
- "u64_add_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.uadd.with.overflow.i64", output_type),
-
- "i8_sub_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.ssub.with.overflow.i8", output_type),
- "i16_sub_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.ssub.with.overflow.i16", output_type),
- "i32_sub_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.ssub.with.overflow.i32", output_type),
- "i64_sub_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.ssub.with.overflow.i64", output_type),
-
- "u8_sub_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.usub.with.overflow.i8", output_type),
- "u16_sub_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.usub.with.overflow.i16", output_type),
- "u32_sub_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.usub.with.overflow.i32", output_type),
- "u64_sub_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.usub.with.overflow.i64", output_type),
-
- "i8_mul_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.smul.with.overflow.i8", output_type),
- "i16_mul_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.smul.with.overflow.i16", output_type),
- "i32_mul_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.smul.with.overflow.i32", output_type),
- "i64_mul_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.smul.with.overflow.i64", output_type),
-
- "u8_mul_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.umul.with.overflow.i8", output_type),
- "u16_mul_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.umul.with.overflow.i16", output_type),
- "u32_mul_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.umul.with.overflow.i32", output_type),
- "u64_mul_with_overflow" =>
- with_overflow_instrinsic(bcx, "llvm.umul.with.overflow.i64", output_type),
-
- _ => {
- // Could we make this an enum rather than a string? does it get
- // checked earlier?
- ccx.sess().span_bug(item.span, "unknown intrinsic");
+ (_, _) => ccx.sess().span_bug(foreign_item.span, "unknown intrinsic")
+ };
+
+ if val_ty(llval) != Type::void(ccx) &&
+ machine::llsize_of_alloc(ccx, val_ty(llval)) != 0 {
+ store_ty(bcx, llval, llresult, ret_ty);
+ }
+
+ // If we made a temporary stack slot, let's clean it up
+ match dest {
+ expr::Ignore => {
+ bcx = glue::drop_ty(bcx, llresult, ret_ty);
}
+ expr::SaveIn(_) => {}
}
- fcx.cleanup();
+
+ Result::new(bcx, llresult)
}
-/// Performs late verification that intrinsics are used correctly. At present,
-/// the only intrinsic that needs such verification is `transmute`.
-pub fn check_intrinsics(ccx: &CrateContext) {
- for transmute_restriction in ccx.tcx
- .transmute_restrictions
- .borrow()
- .iter() {
- let llfromtype = type_of::sizing_type_of(ccx,
- transmute_restriction.from);
- let lltotype = type_of::sizing_type_of(ccx,
- transmute_restriction.to);
- let from_type_size = machine::llbitsize_of_real(ccx, llfromtype);
- let to_type_size = machine::llbitsize_of_real(ccx, lltotype);
- if from_type_size != to_type_size {
- ccx.sess()
- .span_err(transmute_restriction.span,
- format!("transmute called on types with different sizes: \
- {} ({} bit{}) to {} ({} bit{})",
- ty_to_str(ccx.tcx(), transmute_restriction.from),
- from_type_size as uint,
- if from_type_size == 1 {
- ""
- } else {
- "s"
- },
- ty_to_str(ccx.tcx(), transmute_restriction.to),
- to_type_size as uint,
- if to_type_size == 1 {
- ""
- } else {
- "s"
- }).as_slice());
+fn copy_intrinsic(bcx: &Block, allow_overlap: bool, volatile: bool,
+ tp_ty: ty::t, dst: ValueRef, src: ValueRef, count: ValueRef) -> ValueRef {
+ let ccx = bcx.ccx();
+ let lltp_ty = type_of::type_of(ccx, tp_ty);
+ let align = C_i32(ccx, machine::llalign_of_min(ccx, lltp_ty) as i32);
+ let size = machine::llsize_of(ccx, lltp_ty);
+ let int_size = machine::llbitsize_of_real(ccx, ccx.int_type);
+ let name = if allow_overlap {
+ if int_size == 32 {
+ "llvm.memmove.p0i8.p0i8.i32"
+ } else {
+ "llvm.memmove.p0i8.p0i8.i64"
}
- }
- ccx.sess().abort_if_errors();
+ } else {
+ if int_size == 32 {
+ "llvm.memcpy.p0i8.p0i8.i32"
+ } else {
+ "llvm.memcpy.p0i8.p0i8.i64"
+ }
+ };
+
+ let dst_ptr = PointerCast(bcx, dst, Type::i8p(ccx));
+ let src_ptr = PointerCast(bcx, src, Type::i8p(ccx));
+ let llfn = ccx.get_intrinsic(&name);
+
+ Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align,
+ C_bool(ccx, volatile)], [])
}
+fn memset_intrinsic(bcx: &Block, volatile: bool, tp_ty: ty::t,
+ dst: ValueRef, val: ValueRef, count: ValueRef) -> ValueRef {
+ let ccx = bcx.ccx();
+ let lltp_ty = type_of::type_of(ccx, tp_ty);
+ let align = C_i32(ccx, machine::llalign_of_min(ccx, lltp_ty) as i32);
+ let size = machine::llsize_of(ccx, lltp_ty);
+ let name = if machine::llbitsize_of_real(ccx, ccx.int_type) == 32 {
+ "llvm.memset.p0i8.i32"
+ } else {
+ "llvm.memset.p0i8.i64"
+ };
+
+ let dst_ptr = PointerCast(bcx, dst, Type::i8p(ccx));
+ let llfn = ccx.get_intrinsic(&name);
+
+ Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align,
+ C_bool(ccx, volatile)], [])
+}
+
+fn count_zeros_intrinsic(bcx: &Block, name: &'static str, val: ValueRef) -> ValueRef {
+ let y = C_bool(bcx.ccx(), false);
+ let llfn = bcx.ccx().get_intrinsic(&name);
+ Call(bcx, llfn, [val, y], [])
+}
+
+fn with_overflow_intrinsic(bcx: &Block, name: &'static str, t: ty::t,
+ a: ValueRef, b: ValueRef) -> ValueRef {
+ let llfn = bcx.ccx().get_intrinsic(&name);
+
+ // Convert `i1` to a `bool`, and write it to the out parameter
+ let val = Call(bcx, llfn, [a, b], []);
+ let result = ExtractValue(bcx, val, 0);
+ let overflow = ZExt(bcx, ExtractValue(bcx, val, 1), Type::bool(bcx.ccx()));
+ let ret = C_undef(type_of::type_of(bcx.ccx(), t));
+ let ret = InsertValue(bcx, ret, result, 0);
+ let ret = InsertValue(bcx, ret, overflow, 1);
+
+ ret
+}
use middle::trans::context::CrateContext;
use middle::trans::type_::Type;
-use lib::llvm::ValueRef;
+use llvm::ValueRef;
pub trait LlvmRepr {
fn llrepr(&self, ccx: &CrateContext) -> String;
impl LlvmRepr for Type {
fn llrepr(&self, ccx: &CrateContext) -> String {
- ccx.tn.type_to_str(*self)
+ ccx.tn.type_to_string(*self)
}
}
impl LlvmRepr for ValueRef {
fn llrepr(&self, ccx: &CrateContext) -> String {
- ccx.tn.val_to_str(*self)
+ ccx.tn.val_to_string(*self)
}
}
// Information concerning the machine representation of various types.
-use lib::llvm::{ValueRef};
-use lib::llvm::False;
-use lib::llvm::llvm;
+use llvm;
+use llvm::{ValueRef};
+use llvm::False;
use middle::trans::common::*;
use middle::trans::type_::Type;
use back::abi;
-use lib::llvm::llvm;
-use lib::llvm::ValueRef;
-use lib;
+use llvm;
+use llvm::ValueRef;
use metadata::csearch;
use middle::subst;
use middle::trans::base::*;
use std::gc::Gc;
use syntax::abi::Rust;
use syntax::parse::token;
-use syntax::{ast, ast_map, visit};
+use syntax::{ast, ast_map, visit, ast_util};
/**
The main "translation" pass for methods. Generates code
return;
}
for method in methods.iter() {
- if method.generics.ty_params.len() == 0u {
+ if ast_util::method_generics(&**method).ty_params.len() == 0u {
let llfn = get_item_val(ccx, method.id);
- trans_fn(ccx, &*method.decl, &*method.body,
+ trans_fn(ccx, ast_util::method_fn_decl(&**method),
+ ast_util::method_body(&**method),
llfn, ¶m_substs::empty(), method.id, []);
} else {
let mut v = TransItemVisitor{ ccx: ccx };
ast_map::NodeTraitMethod(method) => {
let ident = match *method {
ast::Required(ref m) => m.ident,
- ast::Provided(ref m) => m.ident
+ ast::Provided(ref m) => ast_util::method_ident(&**m)
};
ident.name
}
llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl).to_ref(), buf)
});
llvm::LLVMSetInitializer(vt_gvar, tbl);
- llvm::LLVMSetGlobalConstant(vt_gvar, lib::llvm::True);
- lib::llvm::SetLinkage(vt_gvar, lib::llvm::InternalLinkage);
+ llvm::LLVMSetGlobalConstant(vt_gvar, llvm::True);
+ llvm::SetLinkage(vt_gvar, llvm::InternalLinkage);
vt_gvar
}
}
ExprId(0),
substs.clone(),
vtables.clone());
- if m.explicit_self == ast::SelfValue {
- fn_ref = trans_unboxing_shim(bcx,
- fn_ref,
- &*m,
- m_id,
- substs.clone());
+ match m.explicit_self {
+ ast::SelfValue(_) => {
+ fn_ref = trans_unboxing_shim(bcx,
+ fn_ref,
+ &*m,
+ m_id,
+ substs.clone());
+ },
+ _ => {}
}
fn_ref
}
use back::link::exported_name;
use driver::session;
-use lib::llvm::ValueRef;
+use llvm::ValueRef;
use middle::subst;
use middle::subst::Subst;
use middle::trans::base::{set_llvm_fn_attrs, set_inline_hint};
use middle::trans::base::{trans_fn, decl_internal_rust_fn};
use middle::trans::base;
use middle::trans::common::*;
-use middle::trans::intrinsic;
use middle::ty;
use middle::typeck;
use util::ppaux::Repr;
use syntax::abi;
use syntax::ast;
use syntax::ast_map;
+use syntax::ast_util;
use syntax::ast_util::local_def;
use std::hash::{sip, Hash};
hash_id.hash(&mut state);
mono_ty.hash(&mut state);
- exported_name(path,
- format!("h{}", state.result()).as_slice(),
- ccx.link_meta.crateid.version_or_default())
+ exported_name(path, format!("h{}", state.result()).as_slice())
});
debug!("monomorphize_fn mangled to {}", s);
}
}
}
- ast_map::NodeForeignItem(i) => {
- let simple = intrinsic::get_simple_intrinsic(ccx, &*i);
- match simple {
- Some(decl) => decl,
- None => {
- let d = mk_lldecl();
- intrinsic::trans_intrinsic(ccx, d, &*i, &psubsts, ref_id);
- d
- }
- }
- }
ast_map::NodeVariant(v) => {
let parent = ccx.tcx.map.get_parent(fn_id.node);
let tvs = ty::enum_variants(ccx.tcx(), local_def(parent));
ast_map::NodeMethod(mth) => {
let d = mk_lldecl();
set_llvm_fn_attrs(mth.attrs.as_slice(), d);
- trans_fn(ccx, &*mth.decl, &*mth.body, d, &psubsts, mth.id, []);
+ trans_fn(ccx, ast_util::method_fn_decl(&*mth),
+ ast_util::method_body(&*mth), d, &psubsts, mth.id, []);
d
}
ast_map::NodeTraitMethod(method) => {
ast::Provided(mth) => {
let d = mk_lldecl();
set_llvm_fn_attrs(mth.attrs.as_slice(), d);
- trans_fn(ccx, &*mth.decl, &*mth.body, d, &psubsts, mth.id, []);
+ trans_fn(ccx, ast_util::method_fn_decl(&*mth),
+ ast_util::method_body(&*mth), d, &psubsts, mth.id, []);
d
}
_ => {
}
// Ugh -- but this ensures any new variants won't be forgotten
+ ast_map::NodeForeignItem(..) |
ast_map::NodeLifetime(..) |
ast_map::NodeExpr(..) |
ast_map::NodeStmt(..) |
// except according to those terms.
use back::link::mangle_internal_name_by_path_and_seq;
-use lib::llvm::{ValueRef, llvm};
+use llvm;
+use llvm::{ValueRef};
use middle::trans::adt;
use middle::trans::base::*;
use middle::trans::build::*;
use middle::trans::type_::Type;
use middle::trans::type_of::*;
use middle::ty;
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
use std::rc::Rc;
use arena::TypedArena;
debug!("passing {} args:", args.len());
let mut bcx = self.bcx;
for (i, a) in args.iter().enumerate() {
- debug!("arg {}: {}", i, bcx.val_to_str(*a));
+ debug!("arg {}: {}", i, bcx.val_to_string(*a));
}
let result = unpack_result!(bcx, callee::trans_call_inner(
self.bcx, None, mth_ty,
pub fn visit_ty(&mut self, t: ty::t) {
let bcx = self.bcx;
let tcx = bcx.tcx();
- debug!("reflect::visit_ty {}", ty_to_str(bcx.tcx(), t));
+ debug!("reflect::visit_ty {}", ty_to_string(bcx.tcx(), t));
match ty::get(t).sty {
ty::ty_bot => self.leaf("bot"),
ty::ty_trait(..) => {
let extra = [
self.c_slice(token::intern_and_get_ident(
- ty_to_str(tcx, t).as_slice()))
+ ty_to_string(tcx, t).as_slice()))
];
self.visit("trait", extra);
}
ty::ty_trait(..) => {
let extra = [
self.c_slice(token::intern_and_get_ident(
- ty_to_str(tcx, t).as_slice()))
+ ty_to_string(tcx, t).as_slice()))
];
self.visit("trait", extra);
}
let extra = (vec!(
self.c_slice(
- token::intern_and_get_ident(ty_to_str(tcx,
+ token::intern_and_get_ident(ty_to_string(tcx,
t).as_slice())),
self.c_bool(named_fields),
self.c_uint(fields.len())
let fcx = new_fn_ctxt(ccx, llfdecl, -1, false,
ty::mk_u64(), &empty_param_substs,
None, &arena);
- init_function(&fcx, false, ty::mk_u64());
+ let bcx = init_function(&fcx, false, ty::mk_u64());
let arg = unsafe {
//
//
llvm::LLVMGetParam(llfdecl, fcx.arg_pos(0u) as c_uint)
};
- let bcx = fcx.entry_bcx.borrow().clone().unwrap();
let arg = BitCast(bcx, arg, llptrty);
let ret = adt::trans_get_discr(bcx, &*repr, arg, Some(Type::i64(ccx)));
Store(bcx, ret, fcx.llretptr.get().unwrap());
Some(llreturn) => Br(bcx, llreturn),
None => {}
};
- finish_fn(&fcx, bcx);
+ finish_fn(&fcx, bcx, ty::mk_u64());
llfdecl
};
#![allow(non_camel_case_types)]
use back::abi;
-use lib;
-use lib::llvm::{llvm, ValueRef};
+use llvm;
+use llvm::{ValueRef};
use middle::lang_items::StrDupUniqFnLangItem;
use middle::trans::base::*;
use middle::trans::base;
use middle::trans::type_::Type;
use middle::trans::type_of;
use middle::ty;
-use util::ppaux::ty_to_str;
+use util::ppaux::ty_to_string;
use syntax::ast;
use syntax::parse::token::InternedString;
}
impl VecTypes {
- pub fn to_str(&self, ccx: &CrateContext) -> String {
+ pub fn to_string(&self, ccx: &CrateContext) -> String {
format!("VecTypes {{unit_ty={}, llunit_ty={}, \
llunit_size={}, llunit_alloc_size={}}}",
- ty_to_str(ccx.tcx(), self.unit_ty),
- ccx.tn.type_to_str(self.llunit_ty),
- ccx.tn.val_to_str(self.llunit_size),
+ ty_to_string(ccx.tcx(), self.unit_ty),
+ ccx.tn.type_to_string(self.llunit_ty),
+ ccx.tn.val_to_string(self.llunit_size),
self.llunit_alloc_size)
}
}
// generate the content.
debug!("trans_fixed_vstore(vstore_expr={}, dest={:?})",
- bcx.expr_to_str(vstore_expr), dest.to_str(bcx.ccx()));
+ bcx.expr_to_string(vstore_expr), dest.to_string(bcx.ccx()));
let vt = vec_types_from_expr(bcx, vstore_expr);
let mut bcx = bcx;
debug!("trans_slice_vstore(vstore_expr={}, dest={})",
- bcx.expr_to_str(vstore_expr), dest.to_str(ccx));
+ bcx.expr_to_string(vstore_expr), dest.to_string(ccx));
// Handle the &"..." case:
match content_expr.node {
// Handle the &[...] case:
let vt = vec_types_from_expr(bcx, vstore_expr);
let count = elements_required(bcx, content_expr);
- debug!("vt={}, count={:?}", vt.to_str(ccx), count);
+ debug!("vt={}, count={:?}", vt.to_string(ccx), count);
let llcount = C_uint(ccx, count);
let llfixed;
if count == 0 {
- // Zero-length array: just use NULL as the data pointer
- llfixed = C_null(vt.llunit_ty.ptr_to());
+ // Just create a zero-sized alloca to preserve
+ // the non-null invariant of the inner slice ptr
+ llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
} else {
// Make a fixed-length backing array and allocate it on the stack.
llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount);
*/
debug!("trans_lit_str(lit_expr={}, dest={})",
- bcx.expr_to_str(lit_expr),
- dest.to_str(bcx.ccx()));
+ bcx.expr_to_string(lit_expr),
+ dest.to_string(bcx.ccx()));
match dest {
Ignore => bcx,
* the array elements into them.
*/
- debug!("trans_uniq_vstore(vstore_expr={})", bcx.expr_to_str(vstore_expr));
+ debug!("trans_uniq_vstore(vstore_expr={})", bcx.expr_to_string(vstore_expr));
let fcx = bcx.fcx;
let ccx = fcx.ccx;
let dataptr = get_dataptr(bcx, val);
debug!("alloc_uniq_vec() returned val={}, dataptr={}",
- bcx.val_to_str(val), bcx.val_to_str(dataptr));
+ bcx.val_to_string(val), bcx.val_to_string(dataptr));
let bcx = write_content(bcx, &vt, vstore_expr,
content_expr, SaveIn(dataptr));
let mut bcx = bcx;
debug!("write_content(vt={}, dest={}, vstore_expr={:?})",
- vt.to_str(bcx.ccx()),
- dest.to_str(bcx.ccx()),
- bcx.expr_to_str(vstore_expr));
+ vt.to_string(bcx.ccx()),
+ dest.to_string(bcx.ccx()),
+ bcx.expr_to_string(vstore_expr));
match content_expr.node {
ast::ExprLit(lit) => {
for (i, element) in elements.iter().enumerate() {
let lleltptr = GEPi(bcx, lldest, [i]);
debug!("writing index {:?} with lleltptr={:?}",
- i, bcx.val_to_str(lleltptr));
+ i, bcx.val_to_string(lleltptr));
bcx = expr::trans_into(bcx, &**element,
SaveIn(lleltptr));
fcx.schedule_drop_mem(
{ // i < count
let lhs = Load(cond_bcx, loop_counter);
let rhs = count;
- let cond_val = ICmp(cond_bcx, lib::llvm::IntULT, lhs, rhs);
+ let cond_val = ICmp(cond_bcx, llvm::IntULT, lhs, rhs);
CondBr(cond_bcx, cond_val, body_bcx.llbb, next_bcx.llbb);
}
let data_ptr =
Phi(header_bcx, val_ty(data_ptr), [data_ptr], [bcx.llbb]);
let not_yet_at_end =
- ICmp(header_bcx, lib::llvm::IntULT, data_ptr, data_end_ptr);
+ ICmp(header_bcx, llvm::IntULT, data_ptr, data_end_ptr);
let body_bcx = fcx.new_temp_block("iter_vec_loop_body");
let next_bcx = fcx.new_temp_block("iter_vec_next");
CondBr(header_bcx, not_yet_at_end, body_bcx.llbb, next_bcx.llbb);
#![allow(non_uppercase_pattern_statics)]
-use lib::llvm::{llvm, TypeRef, Bool, False, True, TypeKind};
-use lib::llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};
+use llvm;
+use llvm::{TypeRef, Bool, False, True, TypeKind, ValueRef};
+use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};
use middle::trans::context::CrateContext;
use std::c_str::ToCStr;
use std::mem;
+use std::cell::RefCell;
+use std::collections::HashMap;
+use std::str::raw::from_c_str;
-use libc::{c_uint};
+use libc::{c_uint, c_void, free};
#[deriving(Clone, PartialEq, Show)]
pub struct Type {
}
pub fn bool(ccx: &CrateContext) -> Type {
- Type::i1(ccx)
+ Type::i8(ccx)
}
pub fn char(ccx: &CrateContext) -> Type {
}
}
}
+
+
+/* Memory-managed object interface to type handles. */
+
+pub struct TypeNames {
+ named_types: RefCell<HashMap<String, TypeRef>>,
+}
+
+impl TypeNames {
+ pub fn new() -> TypeNames {
+ TypeNames {
+ named_types: RefCell::new(HashMap::new())
+ }
+ }
+
+ pub fn associate_type(&self, s: &str, t: &Type) {
+ assert!(self.named_types.borrow_mut().insert(s.to_string(),
+ t.to_ref()));
+ }
+
+ pub fn find_type(&self, s: &str) -> Option<Type> {
+ self.named_types.borrow().find_equiv(&s).map(|x| Type::from_ref(*x))
+ }
+
+ pub fn type_to_string(&self, ty: Type) -> String {
+ unsafe {
+ let s = llvm::LLVMTypeToString(ty.to_ref());
+ let ret = from_c_str(s);
+ free(s as *mut c_void);
+ ret.to_string()
+ }
+ }
+
+ pub fn types_to_str(&self, tys: &[Type]) -> String {
+ let strs: Vec<String> = tys.iter().map(|t| self.type_to_string(*t)).collect();
+ format!("[{}]", strs.connect(","))
+ }
+
+ pub fn val_to_string(&self, val: ValueRef) -> String {
+ unsafe {
+ let s = llvm::LLVMValueToString(val);
+ let ret = from_c_str(s);
+ free(s as *mut c_void);
+ ret.to_string()
+ }
+ }
+}
}
pub fn type_of_explicit_arg(ccx: &CrateContext, arg_ty: ty::t) -> Type {
- let llty = type_of(ccx, arg_ty);
+ let llty = arg_type_of(ccx, arg_ty);
if arg_is_indirect(ccx, arg_ty) {
llty.ptr_to()
} else {
// Arg 0: Output pointer.
// (if the output type is non-immediate)
let use_out_pointer = return_uses_outptr(cx, output);
- let lloutputtype = type_of(cx, output);
+ let lloutputtype = arg_type_of(cx, output);
if use_out_pointer {
atys.push(lloutputtype.ptr_to());
}
type_of_rust_fn(cx, true, f.sig.inputs.as_slice(), f.sig.output)
}
ty::ty_bare_fn(ref f) => {
- if f.abi == abi::Rust || f.abi == abi::RustIntrinsic {
+ if f.abi == abi::Rust {
type_of_rust_fn(cx,
false,
f.sig.inputs.as_slice(),
f.sig.output)
+ } else if f.abi == abi::RustIntrinsic {
+ cx.sess().bug("type_of_fn_from_ty given intrinsic")
} else {
foreign::lltype_for_foreign_fn(cx, fty)
}
llsizingty
}
+pub fn arg_type_of(cx: &CrateContext, t: ty::t) -> Type {
+ if ty::type_is_bool(t) {
+ Type::i1(cx)
+ } else {
+ type_of(cx, t)
+ }
+}
+
// NB: If you update this, be sure to update `sizing_type_of()` as well.
pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
// Check the cache.
t,
t_norm.repr(cx.tcx()),
t_norm,
- cx.tn.type_to_str(llty));
+ cx.tn.type_to_string(llty));
cx.lltypes.borrow_mut().insert(t, llty);
return llty;
}
// avoids creating more than one copy of the enum when one
// of the enum's variants refers to the enum itself.
let repr = adt::represent_type(cx, t);
- let tps = substs.types.get_vec(subst::TypeSpace);
+ let tps = substs.types.get_slice(subst::TypeSpace);
let name = llvm_type_name(cx, an_enum, did, tps);
adt::incomplete_type_of(cx, &*repr, name.as_slice())
}
// in *after* placing it into the type cache. This prevents
// infinite recursion with recursive struct types.
let repr = adt::represent_type(cx, t);
- let tps = substs.types.get_vec(subst::TypeSpace);
+ let tps = substs.types.get_slice(subst::TypeSpace);
let name = llvm_type_name(cx, a_struct, did, tps);
adt::incomplete_type_of(cx, &*repr, name.as_slice())
}
debug!("--> mapped t={} {:?} to llty={}",
t.repr(cx.tcx()),
t,
- cx.tn.type_to_str(llty));
+ cx.tn.type_to_string(llty));
cx.lltypes.borrow_mut().insert(t, llty);
pub fn llvm_type_name(cx: &CrateContext,
what: named_ty,
did: ast::DefId,
- tps: &Vec<ty::t>)
+ tps: &[ty::t])
-> String
{
let name = match what {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use lib::llvm::{llvm, UseRef, ValueRef};
+use llvm;
+use llvm::{UseRef, ValueRef};
use middle::trans::basic_block::BasicBlock;
use middle::trans::common::Block;
use libc::c_uint;
use middle::ty_fold;
use middle::ty_fold::{TypeFoldable,TypeFolder};
use middle;
-use util::ppaux::{note_and_explain_region, bound_region_ptr_to_str};
-use util::ppaux::{trait_store_to_str, ty_to_str};
+use util::ppaux::{note_and_explain_region, bound_region_ptr_to_string};
+use util::ppaux::{trait_store_to_string, ty_to_string};
use util::ppaux::{Repr, UserString};
use util::common::{indenter};
use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet, FnvHashMap};
}
pub fn has_type_params(&self, space: subst::ParamSpace) -> bool {
- !self.types.get_vec(space).is_empty()
+ !self.types.is_empty_in(space)
}
}
fn type_requires(cx: &ctxt, seen: &mut Vec<DefId>,
r_ty: t, ty: t) -> bool {
debug!("type_requires({}, {})?",
- ::util::ppaux::ty_to_str(cx, r_ty),
- ::util::ppaux::ty_to_str(cx, ty));
+ ::util::ppaux::ty_to_string(cx, r_ty),
+ ::util::ppaux::ty_to_string(cx, ty));
let r = {
get(r_ty).sty == get(ty).sty ||
};
debug!("type_requires({}, {})? {}",
- ::util::ppaux::ty_to_str(cx, r_ty),
- ::util::ppaux::ty_to_str(cx, ty),
+ ::util::ppaux::ty_to_string(cx, r_ty),
+ ::util::ppaux::ty_to_string(cx, ty),
r);
return r;
}
fn subtypes_require(cx: &ctxt, seen: &mut Vec<DefId>,
r_ty: t, ty: t) -> bool {
debug!("subtypes_require({}, {})?",
- ::util::ppaux::ty_to_str(cx, r_ty),
- ::util::ppaux::ty_to_str(cx, ty));
+ ::util::ppaux::ty_to_string(cx, r_ty),
+ ::util::ppaux::ty_to_string(cx, ty));
let r = match get(ty).sty {
// fixed length vectors need special treatment compared to
};
debug!("subtypes_require({}, {})? {}",
- ::util::ppaux::ty_to_str(cx, r_ty),
- ::util::ppaux::ty_to_str(cx, ty),
+ ::util::ppaux::ty_to_string(cx, r_ty),
+ ::util::ppaux::ty_to_string(cx, ty),
r);
return r;
fn type_structurally_recursive(cx: &ctxt, sp: Span, seen: &mut Vec<DefId>,
ty: t) -> Representability {
debug!("type_structurally_recursive: {}",
- ::util::ppaux::ty_to_str(cx, ty));
+ ::util::ppaux::ty_to_string(cx, ty));
// Compare current type to previously seen types
match get(ty).sty {
}
debug!("is_type_representable: {}",
- ::util::ppaux::ty_to_str(cx, ty));
+ ::util::ppaux::ty_to_string(cx, ty));
// To avoid a stack overflow when checking an enum variant or struct that
// contains a different, structurally recursive type, maintain a stack
Some(t) => t.clone(),
None => cx.sess.bug(
format!("node_id_to_trait_ref: no trait ref for node `{}`",
- cx.map.node_to_str(id)).as_slice())
+ cx.map.node_to_string(id)).as_slice())
}
}
Some(t) => t,
None => cx.sess.bug(
format!("node_id_to_type: no type for node `{}`",
- cx.map.node_to_str(id)).as_slice())
+ cx.map.node_to_string(id)).as_slice())
}
}
format!("the {}th autoderef failed: \
{}",
i,
- ty_to_str(cx, adjusted_ty))
+ ty_to_string(cx, adjusted_ty))
.as_slice());
}
}
// the deref method invoked for `*a` always yields an `&T`
ast::ExprUnary(ast::UnDeref, _) => LvalueExpr,
+ // the index method invoked for `a[i]` always yields an `&T`
+ ast::ExprIndex(..) => LvalueExpr,
+
// in the general case, result could be any type, use DPS
_ => RvalueDpsExpr
};
rslt
}
-pub fn ty_sort_str(cx: &ctxt, t: t) -> String {
+pub fn ty_sort_string(cx: &ctxt, t: t) -> String {
match get(t).sty {
ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) |
ty_uint(_) | ty_float(_) | ty_str => {
- ::util::ppaux::ty_to_str(cx, t)
+ ::util::ppaux::ty_to_string(cx, t)
}
ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)),
terr_mismatch => "types differ".to_string(),
terr_fn_style_mismatch(values) => {
format!("expected {} fn but found {} fn",
- values.expected.to_str(),
- values.found.to_str())
+ values.expected.to_string(),
+ values.found.to_string())
}
terr_abi_mismatch(values) => {
format!("expected {} fn but found {} fn",
- values.expected.to_str(),
- values.found.to_str())
+ values.expected.to_string(),
+ values.found.to_string())
}
terr_onceness_mismatch(values) => {
format!("expected {} fn but found {} fn",
- values.expected.to_str(),
- values.found.to_str())
+ values.expected.to_string(),
+ values.found.to_string())
}
terr_sigil_mismatch(values) => {
format!("expected {}, found {}",
terr_regions_insufficiently_polymorphic(br, _) => {
format!("expected bound lifetime parameter {}, \
but found concrete lifetime",
- bound_region_ptr_to_str(cx, br))
+ bound_region_ptr_to_string(cx, br))
}
terr_regions_overly_polymorphic(br, _) => {
format!("expected concrete lifetime, \
but found bound lifetime parameter {}",
- bound_region_ptr_to_str(cx, br))
+ bound_region_ptr_to_string(cx, br))
}
terr_trait_stores_differ(_, ref values) => {
format!("trait storage differs: expected `{}` but found `{}`",
- trait_store_to_str(cx, (*values).expected),
- trait_store_to_str(cx, (*values).found))
+ trait_store_to_string(cx, (*values).expected),
+ trait_store_to_string(cx, (*values).found))
}
terr_sorts(values) => {
format!("expected {} but found {}",
- ty_sort_str(cx, values.expected),
- ty_sort_str(cx, values.found))
+ ty_sort_string(cx, values.expected),
+ ty_sort_string(cx, values.found))
}
terr_traits(values) => {
format!("expected trait `{}` but found trait `{}`",
}
terr_int_mismatch(ref values) => {
format!("expected `{}` but found `{}`",
- values.expected.to_str(),
- values.found.to_str())
+ values.expected.to_string(),
+ values.found.to_string())
}
terr_float_mismatch(ref values) => {
format!("expected `{}` but found `{}`",
- values.expected.to_str(),
- values.found.to_str())
+ values.expected.to_string(),
+ values.found.to_string())
}
terr_variadic_mismatch(ref values) => {
format!("expected {} fn but found {} function",
}
pub fn item_path_str(cx: &ctxt, id: ast::DefId) -> String {
- with_path(cx, id, |path| ast_map::path_to_str(path)).to_string()
+ with_path(cx, id, |path| ast_map::path_to_string(path)).to_string()
}
pub enum DtorKind {
pub fn each_attr(tcx: &ctxt, did: DefId, f: |&ast::Attribute| -> bool) -> bool {
if is_local(did) {
let item = tcx.map.expect_item(did.node);
- item.attrs.iter().advance(|attr| f(attr))
+ item.attrs.iter().all(|attr| f(attr))
} else {
info!("getting foreign attrs");
let mut cont = true;
csearch::get_item_attrs(&tcx.sess.cstore, did, |attrs| {
if cont {
- cont = attrs.iter().advance(|attr| f(attr));
+ cont = attrs.iter().all(|attr| f(attr));
}
});
info!("done");
None => {
cx.sess.bug(
format!("ID not mapped to super-struct: {}",
- cx.map.node_to_str(did.node)).as_slice());
+ cx.map.node_to_string(did.node)).as_slice());
}
}
}
_ => {
cx.sess.bug(
format!("ID not mapped to struct fields: {}",
- cx.map.node_to_str(did.node)).as_slice());
+ cx.map.node_to_string(did.node)).as_slice());
}
}
});
}
impl Variance {
- pub fn to_str(self) -> &'static str {
+ pub fn to_string(self) -> &'static str {
match self {
Covariant => "+",
Contravariant => "-",
let mut types = VecPerParamSpace::empty();
for &space in subst::ParamSpace::all().iter() {
push_types_from_defs(tcx, &mut types, space,
- generics.types.get_vec(space));
+ generics.types.get_slice(space));
}
// map bound 'a => free 'a
let mut regions = VecPerParamSpace::empty();
for &space in subst::ParamSpace::all().iter() {
push_region_params(&mut regions, space, free_id,
- generics.regions.get_vec(space));
+ generics.regions.get_slice(space));
}
let free_substs = Substs {
let mut bounds = VecPerParamSpace::empty();
for &space in subst::ParamSpace::all().iter() {
push_bounds_from_defs(tcx, &mut bounds, space, &free_substs,
- generics.types.get_vec(space));
+ generics.types.get_slice(space));
}
debug!("construct_parameter_environment: free_id={} \
fn push_region_params(regions: &mut VecPerParamSpace<ty::Region>,
space: subst::ParamSpace,
free_id: ast::NodeId,
- region_params: &Vec<RegionParameterDef>)
+ region_params: &[RegionParameterDef])
{
for r in region_params.iter() {
regions.push(space, ty::free_region_from_def(free_id, r));
fn push_types_from_defs(tcx: &ty::ctxt,
types: &mut subst::VecPerParamSpace<ty::t>,
space: subst::ParamSpace,
- defs: &Vec<TypeParameterDef>) {
+ defs: &[TypeParameterDef]) {
for (i, def) in defs.iter().enumerate() {
let ty = ty::mk_param(tcx, space, i, def.def_id);
types.push(space, ty);
bounds: &mut subst::VecPerParamSpace<ParamBounds>,
space: subst::ParamSpace,
free_substs: &subst::Substs,
- defs: &Vec<TypeParameterDef>) {
+ defs: &[TypeParameterDef]) {
for def in defs.iter() {
let b = (*def.bounds).subst(tcx, free_substs);
bounds.push(space, b);
use syntax::{ast, ast_util};
use syntax::codemap::Span;
use syntax::owned_slice::OwnedSlice;
-use syntax::print::pprust::{lifetime_to_str, path_to_str};
+use syntax::print::pprust::{lifetime_to_string, path_to_string};
pub trait AstConv {
fn tcx<'a>(&'a self) -> &'a ty::ctxt;
};
debug!("ast_region_to_region(lifetime={} id={}) yields {}",
- lifetime_to_str(lifetime),
+ lifetime_to_string(lifetime),
lifetime.id, r.repr(tcx));
r
};
debug!("opt_ast_region_to_region(opt_lifetime={:?}) yields {}",
- opt_lifetime.as_ref().map(|e| lifetime_to_str(e)),
+ opt_lifetime.as_ref().map(|e| lifetime_to_string(e)),
r.repr(this.tcx()));
r
};
// Convert the type parameters supplied by the user.
- let ty_param_defs = decl_generics.types.get_vec(TypeSpace);
+ let ty_param_defs = decl_generics.types.get_slice(TypeSpace);
let supplied_ty_param_count = path.segments.iter().flat_map(|s| s.types.iter()).count();
let formal_ty_param_count = ty_param_defs.len();
let required_ty_param_count = ty_param_defs.iter()
None => {
tcx.sess.span_bug(ast_ty.span,
format!("unbound path {}",
- path_to_str(path)).as_slice())
+ path_to_string(path)).as_slice())
}
Some(&d) => d
};
.sess
.span_bug(ast_ty.span,
format!("unbound path {}",
- path_to_str(path)).as_slice())
+ path_to_string(path)).as_slice())
}
Some(&d) => d
};
tcx.sess
.span_bug(ast_ty.span,
format!("unbound path {}",
- path_to_str(path)).as_slice())
+ path_to_string(path)).as_slice())
}
Some(&d) => d
};
}
match a_def {
def::DefTrait(_) => {
- let path_str = path_to_str(path);
+ let path_str = path_to_string(path);
tcx.sess.span_err(
ast_ty.span,
format!("reference to trait `{name}` where a \
def::DefMod(id) => {
tcx.sess.span_fatal(ast_ty.span,
format!("found module name used as a type: {}",
- tcx.map.node_to_str(id.node)).as_slice());
+ tcx.map.node_to_string(id.node)).as_slice());
}
def::DefPrimTy(_) => {
fail!("DefPrimTy arm missed in previous ast_ty_to_prim_ty call");
let self_ty = opt_self_info.and_then(|self_info| {
match self_info.explicit_self.node {
ast::SelfStatic => None,
- ast::SelfValue => {
+ ast::SelfValue(_) => {
Some(self_info.untransformed_self_ty)
}
- ast::SelfRegion(ref lifetime, mutability) => {
+ ast::SelfRegion(ref lifetime, mutability, _) => {
let region =
opt_ast_region_to_region(this, &rb,
self_info.explicit_self.span,
ty::mt {ty: self_info.untransformed_self_ty,
mutbl: mutability}))
}
- ast::SelfUniq => {
+ ast::SelfUniq(_) => {
Some(ty::mk_uniq(this.tcx(), self_info.untransformed_self_ty))
}
}
}
}
-pub fn check_struct_pat(pcx: &pat_ctxt, pat_id: ast::NodeId, span: Span,
- expected: ty::t, path: &ast::Path,
+pub fn check_struct_pat(pcx: &pat_ctxt, _pat_id: ast::NodeId, span: Span,
+ _expected: ty::t, _path: &ast::Path,
fields: &[ast::FieldPat], etc: bool,
struct_id: ast::DefId,
substitutions: &subst::Substs) {
- let fcx = pcx.fcx;
+ let _fcx = pcx.fcx;
let tcx = pcx.fcx.ccx.tcx;
let class_fields = ty::lookup_struct_fields(tcx, struct_id);
- // Check to ensure that the struct is the one specified.
- match tcx.def_map.borrow().find(&pat_id) {
- Some(&def::DefStruct(supplied_def_id))
- if supplied_def_id == struct_id => {
- // OK.
- }
- Some(&def::DefStruct(..)) | Some(&def::DefVariant(..)) => {
- let name = pprust::path_to_str(path);
- tcx.sess
- .span_err(span,
- format!("mismatched types: expected `{}` but found \
- `{}`",
- fcx.infcx().ty_to_str(expected),
- name).as_slice());
- }
- _ => {
- tcx.sess.span_bug(span, "resolve didn't write in struct ID");
- }
- }
-
check_struct_pat_fields(pcx, span, fields, class_fields, struct_id,
substitutions, etc);
}
variant_id, substitutions, etc);
}
Some(&def::DefStruct(..)) | Some(&def::DefVariant(..)) => {
- let name = pprust::path_to_str(path);
+ let name = pprust::path_to_string(path);
tcx.sess.span_err(span,
format!("mismatched types: expected `{}` but \
found `{}`",
- fcx.infcx().ty_to_str(expected),
+ fcx.infcx().ty_to_string(expected),
name).as_slice());
}
_ => {
let mut error_happened = false;
match *structure {
ty::ty_struct(cid, ref substs) => {
+ // Verify that the pattern named the right structure.
+ let item_did = tcx.def_map.borrow().get(&pat.id).def_id();
+ let struct_did =
+ ty::ty_to_def_id(
+ ty::lookup_item_type(tcx, item_did).ty).unwrap();
+ if struct_did != cid {
+ tcx.sess
+ .span_err(path.span,
+ format!("`{}` does not name the \
+ structure `{}`",
+ pprust::path_to_string(path),
+ fcx.infcx()
+ .ty_to_string(expected)).as_slice())
+ }
+
check_struct_pat(pcx, pat.id, pat.span, expected, path,
fields.as_slice(), etc, cid, substs);
}
"a structure pattern".to_string(),
None);
match tcx.def_map.borrow().find(&pat.id) {
- Some(&def::DefStruct(supplied_def_id)) => {
+ Some(def) => {
check_struct_pat(pcx,
pat.id,
pat.span,
path,
fields.as_slice(),
etc,
- supplied_def_id,
+ def.def_id(),
&subst::Substs::empty());
}
- _ => () // Error, but we're already in an error case
+ None => {
+ tcx.sess.span_bug(pat.span,
+ "whoops, looks like resolve didn't \
+ write a def in here")
+ }
}
error_happened = true;
}
tcx.sess.span_err(
span,
format!("type `{}` cannot be dereferenced",
- fcx.infcx().ty_to_str(expected)).as_slice());
+ fcx.infcx().ty_to_string(expected)).as_slice());
fcx.write_error(pat_id);
}
_ => {
module as the type itself).
Inherent candidates are not always derived from impls. If you have a
-trait instance, such as a value of type `Box<ToStr>`, then the trait
-methods (`to_str()`, in this case) are inherently associated with it.
+trait instance, such as a value of type `Box<ToString>`, then the trait
+methods (`to_string()`, in this case) are inherently associated with it.
Another case is type parameters, in which case the methods of their
bounds are inherent.
Extension candidates are derived from imported traits. If I have the
-trait `ToStr` imported, and I call `to_str()` on a value of type `T`,
-then we will go off to find out whether there is an impl of `ToStr`
+trait `ToString` imported, and I call `to_string()` on a value of type `T`,
+then we will go off to find out whether there is an impl of `ToString`
for `T`. These kinds of method calls are called "extension methods".
They can be defined in any module, not only the one that defined `T`.
Furthermore, you must import the trait to call such a method.
// The subst we get in has Err as the "Self" type. For an object
// type, we don't put any type into the Self paramspace, so let's
// make a copy of rcvr_substs that has the Self paramspace empty.
- obj_substs.types.get_mut_vec(subst::SelfSpace).pop().unwrap();
+ obj_substs.types.pop(subst::SelfSpace).unwrap();
match method_ty.explicit_self {
ast::SelfStatic => {
tcx.sess.span_bug(span, "static method for object type receiver");
}
- ast::SelfValue => {
+ ast::SelfValue(_) => {
let tr = ty::mk_trait(tcx, trait_def_id, obj_substs,
ty::empty_builtin_bounds());
ty::mk_uniq(tcx, tr)
}
- ast::SelfRegion(..) | ast::SelfUniq => {
+ ast::SelfRegion(..) | ast::SelfUniq(..) => {
let transformed_self_ty = *method_ty.fty.sig.inputs.get(0);
match ty::get(transformed_self_ty).sty {
ty::ty_rptr(r, mt) => { // must be SelfRegion
autoderefs: uint)
-> Option<Option<MethodCallee>> {
debug!("search_step: self_ty={} autoderefs={}",
- self.ty_to_str(self_ty), autoderefs);
+ self.ty_to_string(self_ty), autoderefs);
match self.deref_args {
check::DontDerefArgs => {
did: DefId,
substs: &subst::Substs) {
debug!("push_inherent_candidates_from_object(did={}, substs={})",
- self.did_to_str(did),
+ self.did_to_string(did),
substs.repr(self.tcx()));
let _indenter = indenter();
let tcx = self.tcx();
None => None,
Some(method) => {
debug!("(searching for autoderef'd method) writing \
- adjustment {:?} for {}", adjustment, self.ty_to_str( self_ty));
+ adjustment {:?} for {}", adjustment, self.ty_to_string( self_ty));
match adjustment {
Some((self_expr_id, adj)) => {
self.fcx.write_adjustment(self_expr_id, adj);
fn auto_slice_vec(&self, mt: ty::mt, autoderefs: uint) -> Option<MethodCallee> {
let tcx = self.tcx();
- debug!("auto_slice_vec {}", ppaux::ty_to_str(tcx, mt.ty));
+ debug!("auto_slice_vec {}", ppaux::ty_to_string(tcx, mt.ty));
// First try to borrow to a slice
let entry = self.search_for_some_kind_of_autorefd_method(
* `~[]` to `&[]`.
*/
- debug!("search_for_autosliced_method {}", ppaux::ty_to_str(self.tcx(), self_ty));
+ debug!("search_for_autosliced_method {}", ppaux::ty_to_string(self.tcx(), self_ty));
let sty = ty::get(self_ty).sty.clone();
match sty {
ty_infer(TyVar(_)) => {
self.bug(format!("unexpected type: {}",
- self.ty_to_str(self_ty)).as_slice());
+ self.ty_to_string(self_ty)).as_slice());
}
}
}
}
fn search_for_method(&self, rcvr_ty: ty::t) -> Option<MethodCallee> {
- debug!("search_for_method(rcvr_ty={})", self.ty_to_str(rcvr_ty));
+ debug!("search_for_method(rcvr_ty={})", self.ty_to_string(rcvr_ty));
let _indenter = indenter();
// I am not sure that inherent methods should have higher
let tcx = self.tcx();
debug!("confirm_candidate(rcvr_ty={}, candidate={})",
- self.ty_to_str(rcvr_ty),
+ self.ty_to_string(rcvr_ty),
candidate.repr(self.tcx()));
self.enforce_object_limitations(candidate);
let m_regions =
self.fcx.infcx().region_vars_for_defs(
self.span,
- candidate.method_ty.generics.regions.get_vec(subst::FnSpace));
+ candidate.method_ty.generics.regions.get_slice(subst::FnSpace));
let all_substs = candidate.rcvr_substs.clone().with_method(m_types, m_regions);
fn_style: bare_fn_ty.fn_style,
abi: bare_fn_ty.abi.clone(),
});
- debug!("after replacing bound regions, fty={}", self.ty_to_str(fty));
+ debug!("after replacing bound regions, fty={}", self.ty_to_string(fty));
// Before, we only checked whether self_ty could be a subtype
// of rcvr_ty; now we actually make it so (this may cause
Err(_) => {
self.bug(format!(
"{} was a subtype of {} but now is not?",
- self.ty_to_str(rcvr_ty),
- self.ty_to_str(transformed_self_ty)).as_slice());
+ self.ty_to_string(rcvr_ty),
+ self.ty_to_string(transformed_self_ty)).as_slice());
}
}
through an object");
}
- ast::SelfValue | ast::SelfRegion(..) | ast::SelfUniq => {}
+ ast::SelfValue(_) | ast::SelfRegion(..) | ast::SelfUniq(_) => {}
}
// reason (a) above
// candidate method's `self_ty`.
fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
debug!("is_relevant(rcvr_ty={}, candidate={})",
- self.ty_to_str(rcvr_ty), candidate.repr(self.tcx()));
+ self.ty_to_string(rcvr_ty), candidate.repr(self.tcx()));
return match candidate.method_ty.explicit_self {
SelfStatic => {
self.report_statics == ReportStaticMethods
}
- SelfValue => {
+ SelfValue(_) => {
debug!("(is relevant?) explicit self is by-value");
match ty::get(rcvr_ty).sty {
ty::ty_uniq(typ) => {
}
}
- SelfRegion(_, m) => {
+ SelfRegion(_, m, _) => {
debug!("(is relevant?) explicit self is a region");
match ty::get(rcvr_ty).sty {
ty::ty_rptr(_, mt) => {
}
}
- SelfUniq => {
+ SelfUniq(_) => {
debug!("(is relevant?) explicit self is a unique pointer");
match ty::get(rcvr_ty).sty {
ty::ty_uniq(typ) => {
self.fcx.tcx()
}
- fn ty_to_str(&self, t: ty::t) -> String {
- self.fcx.infcx().ty_to_str(t)
+ fn ty_to_string(&self, t: ty::t) -> String {
+ self.fcx.infcx().ty_to_string(t)
}
- fn did_to_str(&self, did: DefId) -> String {
+ fn did_to_string(&self, did: DefId) -> String {
ty::item_path_str(self.tcx(), did)
}
};
self.assign(local.id, o_ty);
debug!("Local variable {} is assigned type {}",
- self.fcx.pat_to_str(&*local.pat),
- self.fcx.infcx().ty_to_str(
+ self.fcx.pat_to_string(&*local.pat),
+ self.fcx.infcx().ty_to_string(
self.fcx.inh.locals.borrow().get_copy(&local.id)));
visit::walk_local(self, local, ());
}
self.assign(p.id, None);
debug!("Pattern binding {} is assigned to {}",
token::get_ident(path1.node),
- self.fcx.infcx().ty_to_str(
+ self.fcx.infcx().ty_to_string(
self.fcx.inh.locals.borrow().get_copy(&p.id)));
}
_ => {}
let item = match tcx.map.find(struct_id.node) {
Some(ast_map::NodeItem(item)) => item,
None => fail!("node not in ast map: {}", struct_id.node),
- _ => fail!("expected item, found {}", tcx.map.node_to_str(struct_id.node))
+ _ => fail!("expected item, found {}", tcx.map.node_to_string(struct_id.node))
};
match item.node {
let method_def_id = local_def(method.id);
let method_ty = ty::method(ccx.tcx, method_def_id);
let method_generics = &method_ty.generics;
+ let m_body = ast_util::method_body(&*method);
let param_env = ty::construct_parameter_environment(ccx.tcx,
method_generics,
- method.body.id);
+ m_body.id);
let fty = ty::node_id_to_type(ccx.tcx, method.id);
- check_bare_fn(ccx, &*method.decl, &*method.body, method.id, fty, param_env);
+ check_bare_fn(ccx, ast_util::method_fn_decl(&*method),
+ m_body, method.id, fty, param_env);
}
fn check_impl_methods_against_trait(ccx: &CrateCtxt,
compare_impl_method(ccx.tcx,
&*impl_method_ty,
impl_method.span,
- impl_method.body.id,
+ ast_util::method_body(&**impl_method).id,
&**trait_method_ty,
&impl_trait_ref.substs);
}
format!(
"method `{}` is not a member of trait `{}`",
token::get_ident(impl_method_ty.ident),
- pprust::path_to_str(&ast_trait_ref.path)).as_slice());
+ pprust::path_to_string(&ast_trait_ref.path)).as_slice());
}
}
}
for trait_method in trait_methods.iter() {
let is_implemented =
impl_methods.iter().any(
- |m| m.ident.name == trait_method.ident.name);
+ |m| ast_util::method_ident(&**m).name == trait_method.ident.name);
let is_provided =
provided_methods.iter().any(
|m| m.ident.name == trait_method.ident.name);
format!("method `{}` has a `{}` declaration in the impl, \
but not in the trait",
token::get_ident(trait_m.ident),
- pprust::explicit_self_to_str(
+ pprust::explicit_self_to_string(
impl_m.explicit_self)).as_slice());
return;
}
format!("method `{}` has a `{}` declaration in the trait, \
but not in the impl",
token::get_ident(trait_m.ident),
- pprust::explicit_self_to_str(
+ pprust::explicit_self_to_string(
trait_m.explicit_self)).as_slice());
return;
}
return;
}
- let it = trait_m.generics.types.get_vec(subst::FnSpace).iter()
- .zip(impl_m.generics.types.get_vec(subst::FnSpace).iter());
+ let it = trait_m.generics.types.get_slice(subst::FnSpace).iter()
+ .zip(impl_m.generics.types.get_slice(subst::FnSpace).iter());
// This code is best explained by example. Consider a trait:
//
let trait_to_skol_substs =
trait_to_impl_substs
.subst(tcx, &impl_to_skol_substs)
- .with_method(skol_tps.get_vec(subst::FnSpace).clone(),
- skol_regions.get_vec(subst::FnSpace).clone());
+ .with_method(Vec::from_slice(skol_tps.get_slice(subst::FnSpace)),
+ Vec::from_slice(skol_regions.get_slice(subst::FnSpace)));
let trait_fty = ty::mk_bare_fn(tcx, trait_m.fty.clone());
let trait_fty = trait_fty.subst(tcx, &trait_to_skol_substs);
declaration",
token::get_ident(trait_m.ident),
i,
- ppaux::trait_ref_to_str(
+ ppaux::trait_ref_to_string(
tcx,
&*impl_trait_bound)).as_slice())
}
let t_e = fcx.expr_ty(e);
- debug!("t_1={}", fcx.infcx().ty_to_str(t_1));
- debug!("t_e={}", fcx.infcx().ty_to_str(t_e));
+ debug!("t_1={}", fcx.infcx().ty_to_string(t_1));
+ debug!("t_e={}", fcx.infcx().ty_to_string(t_e));
if ty::type_is_error(t_e) {
fcx.write_error(id);
fcx.type_error_message(span, |actual| {
format!("cast from nil: `{}` as `{}`",
actual,
- fcx.infcx().ty_to_str(t_1))
+ fcx.infcx().ty_to_string(t_1))
}, t_e, None);
} else if ty::type_is_nil(t_1) {
fcx.type_error_message(span, |actual| {
format!("cast to nil: `{}` as `{}`",
actual,
- fcx.infcx().ty_to_str(t_1))
+ fcx.infcx().ty_to_string(t_1))
}, t_e, None);
}
format!("illegal cast; cast through an \
integer first: `{}` as `{}`",
actual,
- fcx.infcx().ty_to_str(t_1))
+ fcx.infcx().ty_to_string(t_1))
}, t_e, None);
}
// casts from C-like enums are allowed
fcx.type_error_message(span, |actual| {
format!("non-scalar cast: `{}` as `{}`",
actual,
- fcx.infcx().ty_to_str(t_1))
+ fcx.infcx().ty_to_string(t_1))
+ }, t_e, None);
+ } else if ty::type_is_unsafe_ptr(t_e) && t_1_is_float {
+ fcx.type_error_message(span, |actual| {
+ format!("cannot cast from pointer to float directly: `{}` as `{}`; cast through an \
+ integer first",
+ actual,
+ fcx.infcx().ty_to_string(t_1))
}, t_e, None);
}
#[inline]
pub fn write_ty(&self, node_id: ast::NodeId, ty: ty::t) {
debug!("write_ty({}, {}) in fcx {}",
- node_id, ppaux::ty_to_str(self.tcx(), ty), self.tag());
+ node_id, ppaux::ty_to_string(self.tcx(), ty), self.tag());
self.inh.node_types.borrow_mut().insert(node_id, ty);
}
ast_ty_to_ty(self, self.infcx(), ast_t)
}
- pub fn pat_to_str(&self, pat: &ast::Pat) -> String {
+ pub fn pat_to_string(&self, pat: &ast::Pat) -> String {
pat.repr(self.tcx())
}
None => {
self.tcx().sess.bug(
format!("no type for node {}: {} in fcx {}",
- id, self.tcx().map.node_to_str(id),
+ id, self.tcx().map.node_to_string(id),
self.tag()).as_slice());
}
}
None => {
self.tcx().sess.bug(
format!("no method entry for node {}: {} in fcx {}",
- id, self.tcx().map.node_to_str(id),
+ id, self.tcx().map.node_to_string(id),
self.tag()).as_slice());
}
}
}
}
+fn try_overloaded_index(fcx: &FnCtxt,
+ method_call: Option<MethodCall>,
+ expr: &ast::Expr,
+ base_expr: Gc<ast::Expr>,
+ base_ty: ty::t,
+ index_expr: Gc<ast::Expr>,
+ lvalue_pref: LvaluePreference)
+ -> Option<ty::mt> {
+ // Try `IndexMut` first, if preferred.
+ let method = match (lvalue_pref, fcx.tcx().lang_items.index_mut_trait()) {
+ (PreferMutLvalue, Some(trait_did)) => {
+ method::lookup_in_trait(fcx,
+ expr.span,
+ Some(&*base_expr),
+ token::intern("index_mut"),
+ trait_did,
+ base_ty,
+ [],
+ DontAutoderefReceiver,
+ IgnoreStaticMethods)
+ }
+ _ => None,
+ };
+
+ // Otherwise, fall back to `Index`.
+ let method = match (method, fcx.tcx().lang_items.index_trait()) {
+ (None, Some(trait_did)) => {
+ method::lookup_in_trait(fcx,
+ expr.span,
+ Some(&*base_expr),
+ token::intern("index"),
+ trait_did,
+ base_ty,
+ [],
+ DontAutoderefReceiver,
+ IgnoreStaticMethods)
+ }
+ (method, _) => method,
+ };
+
+ // Regardless of whether the lookup succeeds, check the method arguments
+ // so that we have *some* type for each argument.
+ let method_type = match method {
+ Some(ref method) => method.ty,
+ None => ty::mk_err()
+ };
+ check_method_argument_types(fcx,
+ expr.span,
+ method_type,
+ expr,
+ [base_expr, index_expr],
+ DoDerefArgs,
+ DontTupleArguments);
+
+ match method {
+ Some(method) => {
+ let ref_ty = ty::ty_fn_ret(method.ty);
+ match method_call {
+ Some(method_call) => {
+ fcx.inh.method_map.borrow_mut().insert(method_call,
+ method);
+ }
+ None => {}
+ }
+ ty::deref(ref_ty, true)
+ }
+ None => None,
+ }
+}
+
fn check_method_argument_types(fcx: &FnCtxt,
sp: Span,
method_fn_ty: ty::t,
};
debug!("check_argument_types: formal_tys={:?}",
- formal_tys.iter().map(|t| fcx.infcx().ty_to_str(*t)).collect::<Vec<String>>());
+ formal_tys.iter().map(|t| fcx.infcx().ty_to_string(*t)).collect::<Vec<String>>());
// Check the arguments.
// We do this in a pretty awful way: first we typecheck any arguments
let ity = ty::lookup_item_type(tcx, did);
let (n_tps, rps, raw_ty) =
(ity.generics.types.len(subst::TypeSpace),
- ity.generics.regions.get_vec(subst::TypeSpace),
+ ity.generics.regions.get_slice(subst::TypeSpace),
ity.ty);
let rps = vcx.infcx.region_vars_for_defs(span, rps);
operation `{}` not \
supported for floating \
point SIMD vector `{}`",
- ast_util::binop_to_str(op),
+ ast_util::binop_to_string(op),
actual)
},
lhs_t,
|actual| {
format!("binary operation `{}` cannot be applied \
to type `{}`",
- ast_util::binop_to_str(op),
+ ast_util::binop_to_string(op),
actual)
},
lhs_t,
operation `{}=` \
cannot be applied to \
type `{}`",
- ast_util::binop_to_str(op),
+ ast_util::binop_to_string(op),
actual)
},
lhs_t,
trait_did, [lhs_expr, rhs], DontAutoderefReceiver, || {
fcx.type_error_message(ex.span, |actual| {
format!("binary operation `{}` cannot be applied to type `{}`",
- ast_util::binop_to_str(op),
+ ast_util::binop_to_string(op),
actual)
}, lhs_resolved_t, None)
})
expected_sig);
let fty_sig = fn_ty.sig.clone();
let fty = ty::mk_closure(tcx, fn_ty);
- debug!("check_expr_fn fty={}", fcx.infcx().ty_to_str(fty));
+ debug!("check_expr_fn fty={}", fcx.infcx().ty_to_string(fty));
fcx.write_ty(expr.id, fty);
autoderef(fcx, expr.span, expr_t, Some(base.id), lvalue_pref, |base_t, _| {
match ty::get(base_t).sty {
ty::ty_struct(base_id, ref substs) => {
- debug!("struct named {}", ppaux::ty_to_str(tcx, base_t));
+ debug!("struct named {}", ppaux::ty_to_string(tcx, base_t));
let fields = ty::lookup_struct_fields(tcx, base_id);
lookup_field_ty(tcx, base_id, fields.as_slice(),
field.node.name, &(*substs))
// Resolve the path.
let def = tcx.def_map.borrow().find(&id).map(|i| *i);
match def {
- Some(def::DefStruct(type_def_id)) => {
- check_struct_constructor(fcx, id, expr.span, type_def_id,
- fields.as_slice(), base_expr);
- }
Some(def::DefVariant(enum_id, variant_id, _)) => {
check_struct_enum_variant(fcx, id, expr.span, enum_id,
variant_id, fields.as_slice());
}
+ Some(def) => {
+ // Verify that this was actually a struct.
+ let typ = ty::lookup_item_type(fcx.ccx.tcx, def.def_id());
+ match ty::get(typ.ty).sty {
+ ty::ty_struct(struct_did, _) => {
+ check_struct_constructor(fcx,
+ id,
+ expr.span,
+ struct_did,
+ fields.as_slice(),
+ base_expr);
+ }
+ _ => {
+ tcx.sess
+ .span_err(path.span,
+ format!("`{}` does not name a structure",
+ pprust::path_to_string(
+ path)).as_slice())
+ }
+ }
+ }
_ => {
tcx.sess.span_bug(path.span,
- "structure constructor does not name a structure type");
+ "structure constructor wasn't resolved")
}
}
}
} else if ty::type_is_error(idx_t) || ty::type_is_bot(idx_t) {
fcx.write_ty(id, idx_t);
} else {
- let (base_t, autoderefs, field_ty) =
+ let (_, autoderefs, field_ty) =
autoderef(fcx, expr.span, raw_base_t, Some(base.id),
lvalue_pref, |base_t, _| ty::index(base_t));
match field_ty {
fcx.write_autoderef_adjustment(base.id, autoderefs);
}
None => {
- let resolved = structurally_resolved_type(fcx,
- expr.span,
- raw_base_t);
- let ret_ty = lookup_op_method(fcx,
- expr,
- resolved,
- token::intern("index"),
- tcx.lang_items.index_trait(),
- [base.clone(), idx.clone()],
- AutoderefReceiver,
- || {
- fcx.type_error_message(expr.span,
- |actual| {
- format!("cannot index a \
- value of type \
- `{}`", actual)
- },
- base_t,
- None);
- });
- fcx.write_ty(id, ret_ty);
+ // This is an overloaded method.
+ let base_t = structurally_resolved_type(fcx,
+ expr.span,
+ raw_base_t);
+ let method_call = MethodCall::expr(expr.id);
+ match try_overloaded_index(fcx,
+ Some(method_call),
+ expr,
+ *base,
+ base_t,
+ *idx,
+ lvalue_pref) {
+ Some(mt) => fcx.write_ty(id, mt.ty),
+ None => {
+ fcx.type_error_message(expr.span,
+ |actual| {
+ format!("cannot \
+ index a \
+ value of \
+ type `{}`",
+ actual)
+ },
+ base_t,
+ None);
+ fcx.write_ty(id, ty::mk_err())
+ }
+ }
}
}
}
}
debug!("type of expr({}) {} is...", expr.id,
- syntax::print::pprust::expr_to_str(expr));
+ syntax::print::pprust::expr_to_string(expr));
debug!("... {}, expected is {}",
- ppaux::ty_to_str(tcx, fcx.expr_ty(expr)),
- expected.repr(tcx))
+ ppaux::ty_to_string(tcx, fcx.expr_ty(expr)),
+ expected.repr(tcx));
unifier();
}
format!("this type cannot be instantiated without an \
instance of itself; consider using \
`Option<{}>`",
- ppaux::ty_to_str(tcx, item_ty)).as_slice());
+ ppaux::ty_to_string(tcx, item_ty)).as_slice());
false
} else {
true
dynamically sized types may only \
appear as the final type in a \
variant",
- ppaux::ty_to_str(ccx.tcx,
+ ppaux::ty_to_string(ccx.tcx,
*t)).as_slice());
}
}
match v.node.disr_expr {
Some(e) => {
- debug!("disr expr, checking {}", pprust::expr_to_str(&*e));
+ debug!("disr expr, checking {}", pprust::expr_to_string(&*e));
let inh = blank_inherited_fields(ccx);
let fcx = blank_fn_ctxt(ccx, &inh, rty, e.id);
// a problem.
for &space in ParamSpace::all().iter() {
adjust_type_parameters(fcx, span, space, type_defs, &mut substs);
- assert_eq!(substs.types.get_vec(space).len(),
- type_defs.get_vec(space).len());
+ assert_eq!(substs.types.len(space), type_defs.len(space));
adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
- assert_eq!(substs.regions().get_vec(space).len(),
- region_defs.get_vec(space).len());
+ assert_eq!(substs.regions().len(space), region_defs.len(space));
}
fcx.write_ty_substs(node_id, polytype.ty, ty::ItemSubsts {
*/
{
- let type_count = type_defs.get_vec(space).len();
- assert_eq!(substs.types.get_vec(space).len(), 0);
+ let type_count = type_defs.len(space);
+ assert_eq!(substs.types.len(space), 0);
for (i, &typ) in segment.types.iter().enumerate() {
let t = fcx.to_ty(&*typ);
if i < type_count {
but found {} parameter(s)",
type_count,
segment.types.len()).as_slice());
- substs.types.get_mut_vec(space).truncate(0);
+ substs.types.truncate(space, 0);
}
}
}
{
- let region_count = region_defs.get_vec(space).len();
- assert_eq!(substs.regions().get_vec(space).len(), 0);
+ let region_count = region_defs.len(space);
+ assert_eq!(substs.regions().len(space), 0);
for (i, lifetime) in segment.lifetimes.iter().enumerate() {
let r = ast_region_to_region(fcx.tcx(), lifetime);
if i < region_count {
expected {} parameter(s) but found {} parameter(s)",
region_count,
segment.lifetimes.len()).as_slice());
- substs.mut_regions().get_mut_vec(space).truncate(0);
+ substs.mut_regions().truncate(space, 0);
}
}
}
defs: &VecPerParamSpace<ty::TypeParameterDef>,
substs: &mut Substs)
{
- let provided_len = substs.types.get_vec(space).len();
- let desired = defs.get_vec(space).as_slice();
+ let provided_len = substs.types.len(space);
+ let desired = defs.get_slice(space);
let required_len = desired.iter()
.take_while(|d| d.default.is_none())
.count();
// Nothing specified at all: supply inference variables for
// everything.
if provided_len == 0 {
- let provided = substs.types.get_mut_vec(space);
- *provided = fcx.infcx().next_ty_vars(desired.len());
+ substs.types.replace(space,
+ fcx.infcx().next_ty_vars(desired.len()));
return;
}
qualifier,
required_len,
provided_len).as_slice());
- let provided = substs.types.get_mut_vec(space);
- *provided = Vec::from_elem(desired.len(), ty::mk_err());
+ substs.types.replace(space,
+ Vec::from_elem(desired.len(), ty::mk_err()));
return;
}
let default = default.subst_spanned(fcx.tcx(), substs, Some(span));
substs.types.push(space, default);
}
- assert_eq!(substs.types.get_vec(space).len(), desired.len());
+ assert_eq!(substs.types.len(space), desired.len());
debug!("Final substs: {}", substs.repr(fcx.tcx()));
}
defs: &VecPerParamSpace<ty::RegionParameterDef>,
substs: &mut Substs)
{
- let provided = substs.mut_regions().get_mut_vec(space);
- let desired = defs.get_vec(space);
+ let provided_len = substs.mut_regions().len(space);
+ let desired = defs.get_slice(space);
// Enforced by `push_explicit_parameters_from_segment_to_substs()`.
- assert!(provided.len() <= desired.len());
+ assert!(provided_len <= desired.len());
// If nothing was provided, just use inference variables.
- if provided.len() == 0 {
- *provided = fcx.infcx().region_vars_for_defs(span, desired);
+ if provided_len == 0 {
+ substs.mut_regions().replace(
+ space,
+ fcx.infcx().region_vars_for_defs(span, desired));
return;
}
// If just the right number were provided, everybody is happy.
- if provided.len() == desired.len() {
+ if provided_len == desired.len() {
return;
}
expected {} parameter(s) \
but found {} parameter(s)",
desired.len(),
- provided.len()).as_slice());
+ provided_len).as_slice());
- *provided = fcx.infcx().region_vars_for_defs(span, desired);
+ substs.mut_regions().replace(
+ space,
+ fcx.infcx().region_vars_for_defs(span, desired));
}
}
tps: &OwnedSlice<ast::TyParam>,
ty: ty::t) {
debug!("check_bounds_are_used(n_tps={}, ty={})",
- tps.len(), ppaux::ty_to_str(ccx.tcx, ty));
+ tps.len(), ppaux::ty_to_string(ccx.tcx, ty));
// make a vector of booleans initially false, set to true when used
if tps.len() == 0u { return; }
fty,
|| {
format!("intrinsic has wrong type: expected `{}`",
- ppaux::ty_to_str(ccx.tcx, fty))
+ ppaux::ty_to_string(ccx.tcx, fty))
});
}
}
use middle::typeck::MethodCall;
use middle::pat_util;
use util::nodemap::NodeMap;
-use util::ppaux::{ty_to_str, region_to_str, Repr};
+use util::ppaux::{ty_to_string, region_to_string, Repr};
use syntax::ast;
use syntax::codemap::Span;
let r_deref_expr = ty::ReScope(deref_expr.id);
for i in range(0u, derefs) {
debug!("constrain_autoderefs(deref_expr=?, derefd_ty={}, derefs={:?}/{:?}",
- rcx.fcx.infcx().ty_to_str(derefd_ty),
+ rcx.fcx.infcx().ty_to_string(derefd_ty),
i, derefs);
let method_call = MethodCall::autoderef(deref_expr.id, i);
*/
debug!("constrain_index(index_expr=?, indexed_ty={}",
- rcx.fcx.infcx().ty_to_str(indexed_ty));
+ rcx.fcx.infcx().ty_to_string(indexed_ty));
let r_index_expr = ty::ReScope(index_expr.id);
match ty::get(indexed_ty).sty {
|method_call| rcx.resolve_method_type(method_call));
debug!("constrain_regions_in_type_of_node(\
ty={}, ty0={}, id={}, minimum_lifetime={:?})",
- ty_to_str(tcx, ty), ty_to_str(tcx, ty0),
+ ty_to_string(tcx, ty), ty_to_string(tcx, ty0),
id, minimum_lifetime);
constrain_regions_in_type(rcx, minimum_lifetime, origin, ty);
}
let tcx = rcx.fcx.ccx.tcx;
debug!("constrain_regions_in_type(minimum_lifetime={}, ty={})",
- region_to_str(tcx, "", false, minimum_lifetime),
- ty_to_str(tcx, ty));
+ region_to_string(tcx, "", false, minimum_lifetime),
+ ty_to_string(tcx, ty));
relate_nested_regions(tcx, Some(minimum_lifetime), ty, |r_sub, r_sup| {
debug!("relate_nested_regions(r_sub={}, r_sup={})",
let rptr_ty = rcx.resolve_node_type(id);
if !ty::type_is_bot(rptr_ty) && !ty::type_is_error(rptr_ty) {
let tcx = rcx.fcx.ccx.tcx;
- debug!("rptr_ty={}", ty_to_str(tcx, rptr_ty));
+ debug!("rptr_ty={}", ty_to_string(tcx, rptr_ty));
let r = ty::ty_region(tcx, span, rptr_ty);
link_region(rcx, span, r, ty::BorrowKind::from_mutbl(mutbl),
cmt_borrowed);
let mut map = HashMap::new();
let fn_sig = {
let mut f = ty_fold::RegionFolder::regions(tcx, |r| {
- debug!("region r={}", r.to_str());
+ debug!("region r={}", r.to_string());
match r {
ty::ReLateBound(s, br) if s == fn_sig.binder_id => {
*map.find_or_insert_with(br, |_| mapf(br))
}
for &t in all_tys.iter() {
- debug!("relate_free_regions(t={})", ppaux::ty_to_str(tcx, t));
+ debug!("relate_free_regions(t={})", ppaux::ty_to_string(tcx, t));
relate_nested_regions(tcx, None, t, |a, b| {
match (&a, &b) {
(&ty::ReFree(free_a), &ty::ReFree(free_b)) => {
use middle::typeck::check::{FnCtxt, impl_self_ty};
use middle::typeck::check::{structurally_resolved_type};
use middle::typeck::check::writeback;
-use middle::typeck::infer::fixup_err_to_str;
+use middle::typeck::infer::fixup_err_to_string;
use middle::typeck::infer::{resolve_and_force_all_but_regions, resolve_type};
use middle::typeck::infer;
use middle::typeck::{vtable_origin, vtable_res, vtable_param_res};
use syntax::ast;
use syntax::ast_util;
use syntax::codemap::Span;
-use syntax::print::pprust::expr_to_str;
+use syntax::print::pprust::expr_to_string;
use syntax::visit;
use syntax::visit::Visitor;
vcx.tcx().sess.span_fatal(span,
format!("failed to find an implementation of \
trait {} for {}",
- vcx.infcx.trait_ref_to_str(&*trait_ref),
- vcx.infcx.ty_to_str(ty)).as_slice());
+ vcx.infcx.trait_ref_to_string(&*trait_ref),
+ vcx.infcx.ty_to_string(ty)).as_slice());
}
}
true
let tcx = vcx.tcx();
tcx.sess.span_err(span,
format!("expected {}, but found {} ({})",
- ppaux::trait_ref_to_str(tcx, &r_exp_trait_ref),
- ppaux::trait_ref_to_str(tcx, &r_act_trait_ref),
+ ppaux::trait_ref_to_string(tcx, &r_exp_trait_ref),
+ ppaux::trait_ref_to_string(tcx, &r_act_trait_ref),
ty::type_err_to_str(tcx, err)).as_slice());
}
}
debug!("(checking vtable) num 2 relating trait \
ty {} to of_trait_ref {}",
- vcx.infcx.trait_ref_to_str(&*trait_ref),
- vcx.infcx.trait_ref_to_str(&*of_trait_ref));
+ vcx.infcx.trait_ref_to_string(&*trait_ref),
+ vcx.infcx.trait_ref_to_string(&*of_trait_ref));
relate_trait_refs(vcx, span, of_trait_ref, trait_ref.clone());
tcx.sess.span_fatal(span,
format!("cannot determine a type for this bounded type \
parameter: {}",
- fixup_err_to_str(e)).as_slice())
+ fixup_err_to_string(e)).as_slice())
}
Err(_) => {
None
}
debug!("vtable: early_resolve_expr() ex with id {:?} (early: {}): {}",
- ex.id, is_early, expr_to_str(ex));
+ ex.id, is_early, expr_to_string(ex));
let _indent = indenter();
let cx = fcx.ccx;
ex.span,
format!("can only cast an boxed pointer \
to a boxed object, not a {}",
- ty::ty_sort_str(fcx.tcx(), src_ty)).as_slice());
+ ty::ty_sort_string(fcx.tcx(), src_ty)).as_slice());
}
_ => {}
}
ex.span,
format!("can only cast an &-pointer \
to an &-object, not a {}",
- ty::ty_sort_str(fcx.tcx(), src_ty)).as_slice());
+ ty::ty_sort_string(fcx.tcx(), src_ty)).as_slice());
}
_ => {}
}
let did = def.def_id();
let item_ty = ty::lookup_item_type(cx.tcx, did);
debug!("early resolve expr: def {:?} {:?}, {:?}, {}", ex.id, did, def,
- fcx.infcx().ty_to_str(item_ty.ty));
+ fcx.infcx().ty_to_string(item_ty.ty));
debug!("early_resolve_expr: looking up vtables for type params {}",
item_ty.generics.types.repr(fcx.tcx()));
let vcx = fcx.vtable_context();
use syntax::ast;
use syntax::codemap::Span;
-use syntax::print::pprust::pat_to_str;
+use syntax::print::pprust::pat_to_string;
use syntax::visit;
use syntax::visit::Visitor;
self.visit_node_id(ResolvingPattern(p.span), p.id);
debug!("Type for pattern binding {} (id {}) resolved to {}",
- pat_to_str(p),
+ pat_to_string(p),
p.id,
ty::node_id_to_type(self.tcx(), p.id).repr(self.tcx()));
span,
format!("cannot determine a type for \
this expression: {}",
- infer::fixup_err_to_str(e)).as_slice())
+ infer::fixup_err_to_string(e)).as_slice())
}
ResolvingLocal(span) => {
span,
format!("cannot determine a type for \
this local variable: {}",
- infer::fixup_err_to_str(e)).as_slice())
+ infer::fixup_err_to_string(e)).as_slice())
}
ResolvingPattern(span) => {
span,
format!("cannot determine a type for \
this pattern binding: {}",
- infer::fixup_err_to_str(e)).as_slice())
+ infer::fixup_err_to_string(e)).as_slice())
}
ResolvingUpvar(upvar_id) => {
captured variable `{}`: {}",
ty::local_var_name_str(
self.tcx,
- upvar_id.var_id).get().to_str(),
- infer::fixup_err_to_str(e)).as_slice());
+ upvar_id.var_id).get().to_string(),
+ infer::fixup_err_to_string(e)).as_slice());
}
ResolvingImplRes(span) => {
*/
let meth_tps: Vec<ty::t> =
- method.generics.types.get_vec(subst::FnSpace)
+ method.generics.types.get_slice(subst::FnSpace)
.iter()
.map(|def| ty::mk_param_from_def(tcx, def))
.collect();
let meth_regions: Vec<ty::Region> =
- method.generics.regions.get_vec(subst::FnSpace)
+ method.generics.regions.get_slice(subst::FnSpace)
.iter()
.map(|def| ty::ReEarlyBound(def.def_id.node, def.space,
def.index, def.name))
// replace the type parameters declared on the trait with those
// from the impl
for &space in [subst::TypeSpace, subst::SelfSpace].iter() {
- *method_generics.types.get_mut_vec(space) =
- impl_poly_type.generics.types.get_vec(space).clone();
- *method_generics.regions.get_mut_vec(space) =
- impl_poly_type.generics.regions.get_vec(space).clone();
+ method_generics.types.replace(
+ space,
+ Vec::from_slice(impl_poly_type.generics.types.get_slice(space)));
+ method_generics.regions.replace(
+ space,
+ Vec::from_slice(impl_poly_type.generics.regions.get_slice(space)));
}
debug!("subst_receiver_types_in_method_ty: method_generics={}",
use syntax::ast::{TraitTyParamBound, UnboxedFnTyParamBound};
use syntax::ast;
use syntax::ast_map;
-use syntax::ast_util::{local_def, split_trait_methods};
+use syntax::ast_util;
+use syntax::ast_util::{local_def, method_ident, split_trait_methods};
use syntax::codemap::Span;
use syntax::codemap;
use syntax::owned_slice::OwnedSlice;
use syntax::parse::token::special_idents;
use syntax::parse::token;
-use syntax::print::pprust::{path_to_str};
+use syntax::print::pprust::{path_to_string};
use syntax::visit;
struct CollectItemTypesVisitor<'a> {
&ast::Provided(ref m) => {
ty_method_of_trait_method(
ccx, trait_id, &trait_def.generics,
- &m.id, &m.ident, &m.explicit_self,
- &m.generics, &m.fn_style, &*m.decl)
+ &m.id, &ast_util::method_ident(&**m),
+ ast_util::method_explicit_self(&**m),
+ ast_util::method_generics(&**m),
+ &ast_util::method_fn_style(&**m),
+ ast_util::method_fn_decl(&**m))
}
});
let tcx = ccx.tcx;
let mut seen_methods = HashSet::new();
for m in ms.iter() {
- if !seen_methods.insert(m.ident.repr(ccx.tcx)) {
+ if !seen_methods.insert(ast_util::method_ident(&**m).repr(tcx)) {
tcx.sess.span_err(m.span, "duplicate method in trait impl");
}
rcvr_visibility));
let fty = ty::mk_bare_fn(tcx, mty.fty.clone());
debug!("method {} (id {}) has type {}",
- m.ident.repr(ccx.tcx),
+ method_ident(&**m).repr(tcx),
m.id,
- fty.repr(ccx.tcx));
+ fty.repr(tcx));
tcx.tcache.borrow_mut().insert(
local_def(m.id),
Polytype {
rcvr_visibility: ast::Visibility)
-> ty::Method
{
- let fty = astconv::ty_of_method(ccx, m.id, m.fn_style,
+ let fty = astconv::ty_of_method(ccx, m.id, ast_util::method_fn_style(&*m),
untransformed_rcvr_ty,
- m.explicit_self, &*m.decl);
+ *ast_util::method_explicit_self(&*m),
+ ast_util::method_fn_decl(&*m));
// if the method specifies a visibility, use that, otherwise
// inherit the visibility from the impl (so `foo` in `pub impl
// { fn foo(); }` is public, but private in `priv impl { fn
// foo(); }`).
- let method_vis = m.vis.inherit_from(rcvr_visibility);
+ let method_vis = ast_util::method_vis(&*m).inherit_from(rcvr_visibility);
let m_ty_generics =
- ty_generics_for_fn_or_method(ccx, &m.generics,
+ ty_generics_for_fn_or_method(ccx, ast_util::method_generics(&*m),
(*rcvr_ty_generics).clone());
- ty::Method::new(m.ident,
+ ty::Method::new(ast_util::method_ident(&*m),
m_ty_generics,
fty,
- m.explicit_self.node,
+ ast_util::method_explicit_self(&*m).node,
method_vis,
local_def(m.id),
container,
ccx.tcx.sess.span_fatal(
ast_trait_ref.path.span,
format!("`{}` is not a trait",
- path_to_str(&ast_trait_ref.path)).as_slice());
+ path_to_string(&ast_trait_ref.path)).as_slice());
}
}
}
_ => {}
}
- let (generics, sized, supertraits) = match it.node {
- ast::ItemTrait(ref generics, sized, ref supertraits, _) => {
- (generics, sized, supertraits)
+ let (generics, unbound, supertraits) = match it.node {
+ ast::ItemTrait(ref generics, ref unbound, ref supertraits, _) => {
+ (generics, unbound, supertraits)
}
ref s => {
tcx.sess.span_bug(
generics);
let builtin_bounds =
- ensure_supertraits(ccx, it.id, it.span, supertraits, sized);
+ ensure_supertraits(ccx, it.id, it.span, supertraits, unbound);
let substs = mk_item_substs(ccx, &ty_generics);
let trait_def = Rc::new(ty::TraitDef {
id: ast::NodeId,
sp: codemap::Span,
ast_trait_refs: &Vec<ast::TraitRef>,
- sized: ast::Sized)
+ unbound: &Option<ast::TyParamBound>)
-> ty::BuiltinBounds
{
let tcx = ccx.tcx;
}
}
- if sized == ast::StaticSize {
- match tcx.lang_items.require(SizedTraitLangItem) {
- Ok(def_id) => {
- ty::try_add_builtin_trait(tcx, def_id, &mut bounds);
- }
- Err(s) => tcx.sess.err(s.as_slice()),
- };
- }
-
+ add_unsized_bound(ccx, unbound, &mut bounds, "trait", sp);
tcx.supertraits.borrow_mut().insert(local_def(id),
Rc::new(ty_trait_refs));
bounds
debug!("type of {} (id {}) is {}",
token::get_ident(it.ident),
it.id,
- ppaux::ty_to_str(tcx, pty.ty));
+ ppaux::ty_to_string(tcx, pty.ty));
ccx.tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
return pty;
&generics.ty_params, base_generics)
}
+// Add the Sized bound, unless the type parameter is marked as `Sized?`.
+fn add_unsized_bound(ccx: &CrateCtxt,
+ unbound: &Option<ast::TyParamBound>,
+ bounds: &mut ty::BuiltinBounds,
+ desc: &str,
+ span: Span) {
+ let kind_id = ccx.tcx.lang_items.require(SizedTraitLangItem);
+ match unbound {
+ &Some(TraitTyParamBound(ref tpb)) => {
+ // #FIXME(8559) currently requires the unbound to be built-in.
+ let trait_def_id = ty::trait_ref_to_def_id(ccx.tcx, tpb);
+ match kind_id {
+ Ok(kind_id) if trait_def_id != kind_id => {
+ ccx.tcx.sess.span_warn(span,
+ format!("default bound relaxed \
+ for a {}, but this does \
+ nothing because the given \
+ bound is not a default. \
+ Only `Sized?` is supported.",
+ desc).as_slice());
+ ty::try_add_builtin_trait(ccx.tcx,
+ kind_id,
+ bounds);
+ }
+ _ => {}
+ }
+ }
+ _ if kind_id.is_ok() => {
+ ty::try_add_builtin_trait(ccx.tcx,
+ kind_id.unwrap(),
+ bounds);
+ }
+ // No lang item for Sized, so we can't add it as a bound.
+ _ => {}
+ }
+}
+
fn ty_generics(ccx: &CrateCtxt,
space: subst::ParamSpace,
lifetimes: &Vec<ast::Lifetime>,
let bounds = Rc::new(compute_bounds(ccx,
param_ty,
¶m.bounds,
- param.sized,
+ ¶m.unbound,
param.ident,
param.span));
let default = param.default.map(|path| {
ccx: &CrateCtxt,
param_ty: ty::ParamTy,
ast_bounds: &OwnedSlice<ast::TyParamBound>,
- sized: ast::Sized,
+ unbound: &Option<ast::TyParamBound>,
ident: ast::Ident,
span: Span) -> ty::ParamBounds
{
}
}
- if sized == ast::StaticSize {
- match ccx.tcx.lang_items.require(SizedTraitLangItem) {
- Ok(def_id) => { ty::try_add_builtin_trait(ccx.tcx,
- def_id,
- &mut param_bounds.builtin_bounds); },
- // Fixme(13367) after `type` makes it into the snapshot, we can check this properly
- Err(_s) => {}, //ccx.tcx.sess.err(s),
- }
- }
+ add_unsized_bound(ccx,
+ unbound,
+ &mut param_bounds.builtin_bounds,
+ "type parameter",
+ span);
check_bounds_compatible(ccx.tcx, ¶m_bounds, ident, span);
format!("incompatible bounds on type parameter {}, \
bound {} does not allow unsized type",
token::get_ident(ident),
- ppaux::trait_ref_to_str(tcx,
+ ppaux::trait_ref_to_string(tcx,
&*trait_ref)).as_slice());
}
true
let mut substs = subst::Substs::empty();
for &space in subst::ParamSpace::all().iter() {
- let a_tps = a_subst.types.get_vec(space);
- let b_tps = b_subst.types.get_vec(space);
- let tps = if_ok!(self.tps(space,
- a_tps.as_slice(),
- b_tps.as_slice()));
-
- let a_regions = a_subst.regions().get_vec(space);
- let b_regions = b_subst.regions().get_vec(space);
- let r_variances = variances.regions.get_vec(space);
+ let a_tps = a_subst.types.get_slice(space);
+ let b_tps = b_subst.types.get_slice(space);
+ let tps = if_ok!(self.tps(space, a_tps, b_tps));
+
+ let a_regions = a_subst.regions().get_slice(space);
+ let b_regions = b_subst.regions().get_slice(space);
+ let r_variances = variances.regions.get_slice(space);
let regions = if_ok!(relate_region_params(self,
item_def_id,
r_variances,
a_regions,
b_regions));
- *substs.types.get_mut_vec(space) = tps;
- *substs.mut_regions().get_mut_vec(space) = regions;
+ substs.types.replace(space, tps);
+ substs.mut_regions().replace(space, regions);
}
return Ok(substs);
fn relate_region_params<C:Combine>(this: &C,
item_def_id: ast::DefId,
- variances: &Vec<ty::Variance>,
- a_rs: &Vec<ty::Region>,
- b_rs: &Vec<ty::Region>)
+ variances: &[ty::Variance],
+ a_rs: &[ty::Region],
+ b_rs: &[ty::Region])
-> cres<Vec<ty::Region>>
{
let tcx = this.infcx().tcx;
assert_eq!(num_region_params, b_rs.len());
let mut rs = vec!();
for i in range(0, num_region_params) {
- let a_r = *a_rs.get(i);
- let b_r = *b_rs.get(i);
- let variance = *variances.get(i);
+ let a_r = a_rs[i];
+ let b_r = b_rs[i];
+ let variance = variances[i];
let r = match variance {
ty::Invariant => {
eq_regions(this, a_r, b_r)
use syntax::parse::token;
use syntax::print::pprust;
use util::ppaux::UserString;
-use util::ppaux::bound_region_to_str;
+use util::ppaux::bound_region_to_string;
use util::ppaux::note_and_explain_region;
pub trait ErrorReporting {
ty::local_var_name_str(self.tcx,
upvar_id.var_id)
.get()
- .to_str()).as_slice());
+ .to_string()).as_slice());
note_and_explain_region(
self.tcx,
"...the borrowed pointer is valid for ",
ty::local_var_name_str(self.tcx,
upvar_id.var_id)
.get()
- .to_str()).as_slice(),
+ .to_string()).as_slice(),
sup,
"");
}
outlive the enclosing closure",
ty::local_var_name_str(self.tcx,
id).get()
- .to_str()).as_slice());
+ .to_string()).as_slice());
note_and_explain_region(
self.tcx,
"captured variable is valid for ",
var_origins: &[RegionVariableOrigin],
trace_origins: &[(TypeTrace, ty::type_err)],
same_regions: &[SameRegions]) {
- self.give_suggestion(same_regions);
for vo in var_origins.iter() {
self.report_inference_failure(vo.clone());
}
+ self.give_suggestion(same_regions);
for &(ref trace, terr) in trace_origins.iter() {
self.report_type_error(trace.clone(), &terr);
}
Some(ref node) => match *node {
ast_map::NodeItem(ref item) => {
match item.node {
- ast::ItemFn(ref fn_decl, ref pur, _, ref gen, _) => {
+ ast::ItemFn(fn_decl, ref pur, _, ref gen, _) => {
Some((fn_decl, gen, *pur, item.ident, None, item.span))
},
_ => None
}
}
ast_map::NodeMethod(ref m) => {
- Some((&m.decl, &m.generics, m.fn_style,
- m.ident, Some(m.explicit_self.node), m.span))
+ Some((ast_util::method_fn_decl(&**m),
+ ast_util::method_generics(&**m),
+ ast_util::method_fn_style(&**m),
+ ast_util::method_ident(&**m),
+ Some(ast_util::method_explicit_self(&**m).node), m.span))
},
_ => None
},
= node_inner.expect("expect item fn");
let taken = lifetimes_in_scope(self.tcx, scope_id);
let life_giver = LifeGiver::with_taken(taken.as_slice());
- let rebuilder = Rebuilder::new(self.tcx, *fn_decl, expl_self,
+ let rebuilder = Rebuilder::new(self.tcx, fn_decl, expl_self,
generics, same_regions, &life_giver);
let (fn_decl, expl_self, generics) = rebuilder.rebuild();
self.give_expl_lifetime_param(&fn_decl, fn_style, ident,
ident: ty_param.ident,
id: ty_param.id,
bounds: bounds,
+ unbound: ty_param.unbound.clone(),
default: ty_param.default,
span: ty_param.span,
- sized: ty_param.sized,
}
})
}
-> Option<ast::ExplicitSelf_> {
match expl_self_opt {
Some(expl_self) => match expl_self {
- ast::SelfRegion(lt_opt, muta) => match lt_opt {
+ ast::SelfRegion(lt_opt, muta, id) => match lt_opt {
Some(lt) => if region_names.contains(<.name) {
- return Some(ast::SelfRegion(Some(lifetime), muta));
+ return Some(ast::SelfRegion(Some(lifetime), muta, id));
},
None => {
let anon = self.cur_anon.get();
self.inc_and_offset_cur_anon(1);
if anon_nums.contains(&anon) {
self.track_anon(anon);
- return Some(ast::SelfRegion(Some(lifetime), muta));
+ return Some(ast::SelfRegion(Some(lifetime), muta, id));
}
}
},
.sess
.fatal(format!(
"unbound path {}",
- pprust::path_to_str(path)).as_slice())
+ pprust::path_to_string(path)).as_slice())
}
Some(&d) => d
};
opt_explicit_self: Option<ast::ExplicitSelf_>,
generics: &ast::Generics,
span: codemap::Span) {
- let suggested_fn = pprust::fun_to_str(decl, fn_style, ident,
+ let suggested_fn = pprust::fun_to_string(decl, fn_style, ident,
opt_explicit_self, generics);
let msg = format!("consider using an explicit lifetime \
parameter as shown: {}", suggested_fn);
infer::Coercion(_) => " for automatic coercion".to_string(),
infer::LateBoundRegion(_, br) => {
format!(" for {}in function call",
- bound_region_to_str(self.tcx, "lifetime parameter ", true, br))
+ bound_region_to_string(self.tcx, "lifetime parameter ", true, br))
}
infer::BoundRegionInFnType(_, br) => {
format!(" for {}in function type",
- bound_region_to_str(self.tcx, "lifetime parameter ", true, br))
+ bound_region_to_string(self.tcx, "lifetime parameter ", true, br))
}
infer::EarlyBoundRegion(_, name) => {
format!(" for lifetime parameter `{}",
}
infer::UpvarRegion(ref upvar_id, _) => {
format!(" for capture of `{}` by closure",
- ty::local_var_name_str(self.tcx, upvar_id.var_id).get().to_str())
+ ty::local_var_name_str(self.tcx, upvar_id.var_id).get().to_string())
}
};
"...so that closure can access `{}`",
ty::local_var_name_str(self.tcx, upvar_id.var_id)
.get()
- .to_str()).as_slice())
+ .to_string()).as_slice())
}
infer::InfStackClosure(span) => {
self.tcx.sess.span_note(
does not outlive the enclosing closure",
ty::local_var_name_str(
self.tcx,
- id).get().to_str()).as_slice());
+ id).get().to_string()).as_slice());
}
infer::IndexSlice(span) => {
self.tcx.sess.span_note(
_ => None
},
ast_map::NodeMethod(m) => {
- taken.push_all(m.generics.lifetimes.as_slice());
+ taken.push_all(ast_util::method_generics(&*m).lifetimes.as_slice());
Some(m.id)
},
_ => None
let mut lifetime;
loop {
let mut s = String::from_str("'");
- s.push_str(num_to_str(self.counter.get()).as_slice());
+ s.push_str(num_to_string(self.counter.get()).as_slice());
if !self.taken.contains(&s) {
lifetime = name_to_dummy_lifetime(
token::str_to_ident(s.as_slice()).name);
return lifetime;
// 0 .. 25 generates a .. z, 26 .. 51 generates aa .. zz, and so on
- fn num_to_str(counter: uint) -> String {
+ fn num_to_string(counter: uint) -> String {
let mut s = String::new();
let (n, r) = (counter/26 + 1, counter % 26);
let letter: char = from_u32((r+97) as u32).unwrap();
use syntax::ast::{Onceness, FnStyle};
use std::collections::HashMap;
use util::common::{indenter};
-use util::ppaux::mt_to_str;
+use util::ppaux::mt_to_string;
use util::ppaux::Repr;
pub struct Glb<'f>(pub CombineFields<'f>); // "greatest lower bound" (common subtype)
debug!("{}.mts({}, {})",
self.tag(),
- mt_to_str(tcx, a),
- mt_to_str(tcx, b));
+ mt_to_string(tcx, a),
+ mt_to_string(tcx, b));
match (a.mutbl, b.mutbl) {
// If one side or both is mut, then the GLB must use
use middle::typeck::infer::combine::*;
use middle::typeck::infer::glb::Glb;
use middle::typeck::infer::lub::Lub;
-use middle::typeck::infer::unify::{Root, UnifyKey};
+use middle::typeck::infer::unify::*;
use middle::typeck::infer::sub::Sub;
use util::ppaux::Repr;
* - If the variables do not both have an upper bound, we will unify
* the variables and return the unified variable, in which case the
* result is a variable. This is indicated with a `VarResult`
- * return.
- */
+ * return. */
pub fn lattice_vars<L:LatticeDir+Combine,
T:LatticeValue,
K:UnifyKey<Bounds<T>>>(
use syntax::ast::{NormalFn, UnsafeFn};
use syntax::ast::{Onceness, FnStyle};
use syntax::ast::{MutMutable, MutImmutable};
-use util::ppaux::mt_to_str;
+use util::ppaux::mt_to_string;
use util::ppaux::Repr;
pub struct Lub<'f>(pub CombineFields<'f>); // least-upper-bound: common supertype
debug!("{}.mts({}, {})",
self.tag(),
- mt_to_str(tcx, a),
- mt_to_str(tcx, b));
+ mt_to_string(tcx, a),
+ mt_to_string(tcx, b));
if a.mutbl != b.mutbl {
return Err(ty::terr_mutability)
use syntax::codemap;
use syntax::codemap::Span;
use util::common::indent;
-use util::ppaux::{bound_region_to_str, ty_to_str, trait_ref_to_str, Repr};
+use util::ppaux::{bound_region_to_string, ty_to_string, trait_ref_to_string, Repr};
pub mod doc;
pub mod macros;
region_var_bound_by_region_var(RegionVid, RegionVid)
}
-pub fn fixup_err_to_str(f: fixup_err) -> String {
+pub fn fixup_err_to_string(f: fixup_err) -> String {
match f {
unresolved_int_ty(_) => {
"cannot determine the type of this integer; add a suffix to \
pub fn region_vars_for_defs(&self,
span: Span,
- defs: &Vec<ty::RegionParameterDef>)
+ defs: &[ty::RegionParameterDef])
-> Vec<ty::Region> {
defs.iter()
.map(|d| self.next_region_var(EarlyBoundRegion(span, d.name)))
assert!(generics.regions.len(subst::FnSpace) == 0);
let type_parameter_count = generics.types.len(subst::TypeSpace);
- let region_param_defs = generics.regions.get_vec(subst::TypeSpace);
+ let region_param_defs = generics.regions.get_slice(subst::TypeSpace);
let regions = self.region_vars_for_defs(span, region_param_defs);
let type_parameters = self.next_ty_vars(type_parameter_count);
subst::Substs::new_type(type_parameters, regions)
self.report_region_errors(&errors); // see error_reporting.rs
}
- pub fn ty_to_str(&self, t: ty::t) -> String {
- ty_to_str(self.tcx,
+ pub fn ty_to_string(&self, t: ty::t) -> String {
+ ty_to_string(self.tcx,
self.resolve_type_vars_if_possible(t))
}
- pub fn tys_to_str(&self, ts: &[ty::t]) -> String {
- let tstrs: Vec<String> = ts.iter().map(|t| self.ty_to_str(*t)).collect();
+ pub fn tys_to_string(&self, ts: &[ty::t]) -> String {
+ let tstrs: Vec<String> = ts.iter().map(|t| self.ty_to_string(*t)).collect();
format!("({})", tstrs.connect(", "))
}
- pub fn trait_ref_to_str(&self, t: &ty::TraitRef) -> String {
+ pub fn trait_ref_to_string(&self, t: &ty::TraitRef) -> String {
let t = self.resolve_type_vars_in_trait_ref_if_possible(t);
- trait_ref_to_str(self.tcx, &t)
+ trait_ref_to_string(self.tcx, &t)
}
pub fn resolve_type_vars_if_possible(&self, typ: ty::t) -> ty::t {
self.tcx.sess.bug(
format!("resolve_type_vars_if_possible() yielded {} \
when supplied with {}",
- self.ty_to_str(dummy0),
- self.ty_to_str(dummy1)).as_slice());
+ self.ty_to_string(dummy0),
+ self.ty_to_string(dummy1)).as_slice());
}
}
}
Some(e) => {
self.tcx.sess.span_err(sp,
format!("{}{}",
- mk_msg(Some(self.ty_to_str(e)), actual_ty),
+ mk_msg(Some(self.ty_to_string(e)), actual_ty),
error_str).as_slice());
}
}
return;
}
- self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_str(actual_ty), err);
+ self.type_error_message_str(sp, |_e, a| { mk_msg(a) }, self.ty_to_string(actual_ty), err);
}
pub fn report_mismatched_types(&self,
// if I leave out : String, it infers &str and complains
|actual: String| {
format!("mismatched types: expected `{}` but found `{}`",
- self.ty_to_str(resolved_expected),
+ self.ty_to_string(resolved_expected),
actual)
}
}
let rvar = self.next_region_var(
BoundRegionInFnType(trace.origin.span(), br));
debug!("Bound region {} maps to {:?}",
- bound_region_to_str(self.tcx, "", false, br),
+ bound_region_to_string(self.tcx, "", false, br),
rvar);
rvar
});
use middle::typeck::infer::{unresolved_ty};
use syntax::codemap::Span;
use util::common::indent;
-use util::ppaux::{Repr, ty_to_str};
+use util::ppaux::{Repr, ty_to_string};
pub static resolve_nested_tvar: uint = 0b0000000001;
pub static resolve_rvar: uint = 0b0000000010;
self.err = None;
debug!("Resolving {} (modes={:x})",
- ty_to_str(self.infcx.tcx, typ),
+ ty_to_string(self.infcx.tcx, typ),
self.modes);
// n.b. This is a hokey mess because the current fold doesn't
match self.err {
None => {
debug!("Resolved to {} + {} (modes={:x})",
- ty_to_str(self.infcx.tcx, rty),
- ty_to_str(self.infcx.tcx, rty),
+ ty_to_string(self.infcx.tcx, rty),
+ ty_to_string(self.infcx.tcx, rty),
self.modes);
return Ok(rty);
}
use middle::typeck::infer::then;
use middle::typeck::infer::{TypeTrace, Subtype};
use util::common::{indenter};
-use util::ppaux::{bound_region_to_str, Repr};
+use util::ppaux::{bound_region_to_string, Repr};
use syntax::ast::{Onceness, FnStyle, MutImmutable, MutMutable};
replace_late_bound_regions_in_fn_sig(self.get_ref().infcx.tcx, b, |br| {
let skol = self.get_ref().infcx.region_vars.new_skolemized(br);
debug!("Bound region {} skolemized to {:?}",
- bound_region_to_str(self.get_ref().infcx.tcx, "", false, br),
+ bound_region_to_string(self.get_ref().infcx.tcx, "", false, br),
skol);
skol
})
use syntax::codemap::{Span, CodeMap, DUMMY_SP};
use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note};
use syntax::ast;
-use syntax::crateid::CrateId;
-use util::ppaux::{ty_to_str, UserString};
+use util::ppaux::{ty_to_string, UserString};
struct Env<'a> {
krate: ast::Crate,
fn emit(&mut self,
_cmsp: Option<(&codemap::CodeMap, Span)>,
msg: &str,
+ _: Option<&str>,
lvl: Level)
{
remove_message(self, msg, lvl);
let krate_config = Vec::new();
let input = driver::StrInput(source_string.to_owned());
let krate = driver::phase_1_parse_input(&sess, krate_config, &input);
- let krate_id = CrateId { path: "test".to_owned(),
- name: "test".to_owned(),
- version: None };
let (krate, ast_map) =
- driver::phase_2_configure_and_expand(&sess, krate, &krate_id)
+ driver::phase_2_configure_and_expand(&sess, krate, "test")
.expect("phase 2 aborted");
// run just enough stuff to build a tcx:
pub fn assert_subtype(&self, a: ty::t, b: ty::t) {
if !self.is_subtype(a, b) {
fail!("{} is not a subtype of {}, but it should be",
- self.ty_to_str(a),
- self.ty_to_str(b));
+ self.ty_to_string(a),
+ self.ty_to_string(b));
}
}
pub fn assert_not_subtype(&self, a: ty::t, b: ty::t) {
if self.is_subtype(a, b) {
fail!("{} is a subtype of {}, but it shouldn't be",
- self.ty_to_str(a),
- self.ty_to_str(b));
+ self.ty_to_string(a),
+ self.ty_to_string(b));
}
}
self.assert_subtype(b, a);
}
- pub fn ty_to_str(&self, a: ty::t) -> String {
- ty_to_str(self.tcx, a)
+ pub fn ty_to_string(&self, a: ty::t) -> String {
+ ty_to_string(self.tcx, a)
}
pub fn t_fn(&self,
/// Checks that `GLB(t1,t2) == t_glb`
pub fn check_glb(&self, t1: ty::t, t2: ty::t, t_glb: ty::t) {
debug!("check_glb(t1={}, t2={}, t_glb={})",
- self.ty_to_str(t1),
- self.ty_to_str(t2),
- self.ty_to_str(t_glb));
+ self.ty_to_string(t1),
+ self.ty_to_string(t2),
+ self.ty_to_string(t_glb));
match self.glb().tys(t1, t2) {
Err(e) => {
fail!("unexpected error computing LUB: {:?}", e)
match self.lub().tys(t1, t2) {
Err(_) => {}
Ok(t) => {
- fail!("unexpected success computing LUB: {}", self.ty_to_str(t))
+ fail!("unexpected success computing LUB: {}", self.ty_to_string(t))
}
}
}
match self.glb().tys(t1, t2) {
Err(_) => {}
Ok(t) => {
- fail!("unexpected success computing GLB: {}", self.ty_to_str(t))
+ fail!("unexpected success computing GLB: {}", self.ty_to_string(t))
}
}
}
// Functions that write types into the node type table
pub fn write_ty_to_tcx(tcx: &ty::ctxt, node_id: ast::NodeId, ty: ty::t) {
- debug!("write_ty_to_tcx({}, {})", node_id, ppaux::ty_to_str(tcx, ty));
+ debug!("write_ty_to_tcx({}, {})", node_id, ppaux::ty_to_string(tcx, ty));
assert!(!ty::type_needs_infer(ty));
tcx.node_types.borrow_mut().insert(node_id as uint, ty);
}
require_same_types(tcx, None, false, main_span, main_t, se_ty,
|| {
format!("main function expects type: `{}`",
- ppaux::ty_to_str(ccx.tcx, se_ty))
+ ppaux::ty_to_string(ccx.tcx, se_ty))
});
}
_ => {
tcx.sess.span_bug(main_span,
format!("main has a non-function type: found \
`{}`",
- ppaux::ty_to_str(tcx,
+ ppaux::ty_to_string(tcx,
main_t)).as_slice());
}
}
require_same_types(tcx, None, false, start_span, start_t, se_ty,
|| {
format!("start function expects type: `{}`",
- ppaux::ty_to_str(ccx.tcx, se_ty))
+ ppaux::ty_to_string(ccx.tcx, se_ty))
});
}
tcx.sess.span_bug(start_span,
format!("start has a non-function type: found \
`{}`",
- ppaux::ty_to_str(tcx,
+ ppaux::ty_to_string(tcx,
start_t)).as_slice());
}
}
None => {
self.tcx().sess.bug(format!(
"no inferred index entry for {}",
- self.tcx().map.node_to_str(param_id)).as_slice());
+ self.tcx().map.node_to_string(param_id)).as_slice());
}
}
}
let is_inferred;
macro_rules! cannot_happen { () => { {
fail!("invalid parent: {:s} for {:s}",
- tcx.map.node_to_str(parent_id),
- tcx.map.node_to_str(param_id));
+ tcx.map.node_to_string(parent_id),
+ tcx.map.node_to_string(param_id));
} } }
match parent {
InferredIndex(index): InferredIndex,
variance: VarianceTermPtr<'a>) {
debug!("add_constraint(index={}, variance={})",
- index, variance.to_str());
+ index, variance.to_string());
self.constraints.push(Constraint { inferred: InferredIndex(index),
variance: variance });
}
// All type parameters on enums and structs should be
// in the TypeSpace.
- assert!(generics.types.get_vec(subst::SelfSpace).is_empty());
- assert!(generics.types.get_vec(subst::FnSpace).is_empty());
- assert!(generics.regions.get_vec(subst::SelfSpace).is_empty());
- assert!(generics.regions.get_vec(subst::FnSpace).is_empty());
+ assert!(generics.types.is_empty_in(subst::SelfSpace));
+ assert!(generics.types.is_empty_in(subst::FnSpace));
+ assert!(generics.regions.is_empty_in(subst::SelfSpace));
+ assert!(generics.regions.is_empty_in(subst::FnSpace));
self.add_constraints_from_substs(
def_id,
- generics.types.get_vec(subst::TypeSpace),
- generics.regions.get_vec(subst::TypeSpace),
+ generics.types.get_slice(subst::TypeSpace),
+ generics.regions.get_slice(subst::TypeSpace),
substs,
variance);
}
// Traits DO have a Self type parameter, but it is
// erased from object types.
- assert!(!generics.types.get_vec(subst::SelfSpace).is_empty() &&
- substs.types.get_vec(subst::SelfSpace).is_empty());
+ assert!(!generics.types.is_empty_in(subst::SelfSpace) &&
+ substs.types.is_empty_in(subst::SelfSpace));
// Traits never declare region parameters in the self
// space.
- assert!(generics.regions.get_vec(subst::SelfSpace).is_empty());
+ assert!(generics.regions.is_empty_in(subst::SelfSpace));
// Traits never declare type/region parameters in the
// fn space.
- assert!(generics.types.get_vec(subst::FnSpace).is_empty());
- assert!(generics.regions.get_vec(subst::FnSpace).is_empty());
+ assert!(generics.types.is_empty_in(subst::FnSpace));
+ assert!(generics.regions.is_empty_in(subst::FnSpace));
self.add_constraints_from_substs(
def_id,
- generics.types.get_vec(subst::TypeSpace),
- generics.regions.get_vec(subst::TypeSpace),
+ generics.types.get_slice(subst::TypeSpace),
+ generics.regions.get_slice(subst::TypeSpace),
substs,
variance);
}
/// object, etc) appearing in a context with ambient variance `variance`
fn add_constraints_from_substs(&mut self,
def_id: ast::DefId,
- type_param_defs: &Vec<ty::TypeParameterDef>,
- region_param_defs: &Vec<ty::RegionParameterDef>,
+ type_param_defs: &[ty::TypeParameterDef],
+ region_param_defs: &[ty::RegionParameterDef],
substs: &subst::Substs,
variance: VarianceTermPtr<'a>) {
debug!("add_constraints_from_substs(def_id={:?})", def_id);
.param_id,
old_value,
new_value,
- term.to_str());
+ term.to_string());
*self.solutions.get_mut(inferred) = new_value;
changed = true;
loader.plugins
}
+// note that macros aren't expanded yet, and therefore macros can't add plugins.
impl<'a> Visitor<()> for PluginLoader<'a> {
fn visit_view_item(&mut self, vi: &ast::ViewItem, _: ()) {
match vi.node {
_ => (),
}
}
+ fn visit_mac(&mut self, _: &ast::Mac, _:()) {
+ // bummer... can't see plugins inside macros.
+ // do nothing.
+ }
}
impl<'a> PluginLoader<'a> {
* `#[plugin_registrar]` function:
*
* ```rust,ignore
- * #![crate_id = "myplugin"]
+ * #![crate_name = "myplugin"]
* #![crate_type = "dylib"]
* #![feature(plugin_registrar)]
*
use lint::LintPassObject;
use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
-use syntax::ext::base::{IdentTT, ItemDecorator, ItemModifier, BasicMacroExpander};
+use syntax::ext::base::{IdentTT, LetSyntaxTT, ItemDecorator, ItemModifier, BasicMacroExpander};
use syntax::ext::base::{MacroExpanderFn};
use syntax::codemap::Span;
use syntax::parse::token;
IdentTT(ext, _) => IdentTT(ext, Some(self.krate_span)),
ItemDecorator(ext) => ItemDecorator(ext),
ItemModifier(ext) => ItemModifier(ext),
+ // there's probably a nicer way to signal this:
+ LetSyntaxTT(_, _) => fail!("can't register a new LetSyntax!"),
}));
}
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::io;
-use std::io::fs;
-use std::os;
-
-/// Returns an absolute path in the filesystem that `path` points to. The
-/// returned path does not contain any symlinks in its hierarchy.
-pub fn realpath(original: &Path) -> io::IoResult<Path> {
- static MAX_LINKS_FOLLOWED: uint = 256;
- let original = os::make_absolute(original);
-
- // Right now lstat on windows doesn't work quite well
- if cfg!(windows) {
- return Ok(original)
- }
-
- let result = original.root_path();
- let mut result = result.expect("make_absolute has no root_path");
- let mut followed = 0;
-
- for part in original.components() {
- result.push(part);
-
- loop {
- if followed == MAX_LINKS_FOLLOWED {
- return Err(io::standard_error(io::InvalidInput))
- }
-
- match fs::lstat(&result) {
- Err(..) => break,
- Ok(ref stat) if stat.kind != io::TypeSymlink => break,
- Ok(..) => {
- followed += 1;
- let path = try!(fs::readlink(&result));
- result.pop();
- result.push(path);
- }
- }
- }
- }
-
- return Ok(result);
-}
-
-#[cfg(not(windows), test)]
-mod test {
- use std::io;
- use std::io::fs::{File, symlink, mkdir, mkdir_recursive};
- use super::realpath;
- use std::io::TempDir;
-
- #[test]
- fn realpath_works() {
- let tmpdir = TempDir::new("rustc-fs").unwrap();
- let tmpdir = realpath(tmpdir.path()).unwrap();
- let file = tmpdir.join("test");
- let dir = tmpdir.join("test2");
- let link = dir.join("link");
- let linkdir = tmpdir.join("test3");
-
- File::create(&file).unwrap();
- mkdir(&dir, io::UserRWX).unwrap();
- symlink(&file, &link).unwrap();
- symlink(&dir, &linkdir).unwrap();
-
- assert!(realpath(&tmpdir).unwrap() == tmpdir);
- assert!(realpath(&file).unwrap() == file);
- assert!(realpath(&link).unwrap() == file);
- assert!(realpath(&linkdir).unwrap() == dir);
- assert!(realpath(&linkdir.join("link")).unwrap() == file);
- }
-
- #[test]
- fn realpath_works_tricky() {
- let tmpdir = TempDir::new("rustc-fs").unwrap();
- let tmpdir = realpath(tmpdir.path()).unwrap();
-
- let a = tmpdir.join("a");
- let b = a.join("b");
- let c = b.join("c");
- let d = a.join("d");
- let e = d.join("e");
- let f = a.join("f");
-
- mkdir_recursive(&b, io::UserRWX).unwrap();
- mkdir_recursive(&d, io::UserRWX).unwrap();
- File::create(&f).unwrap();
- symlink(&Path::new("../d/e"), &c).unwrap();
- symlink(&Path::new("../f"), &e).unwrap();
-
- assert!(realpath(&c).unwrap() == f);
- assert!(realpath(&e).unwrap() == f);
- }
-}
use middle::ty::{BoundRegion, BrAnon, BrNamed};
use middle::ty::{BrFresh, ctxt};
use middle::ty::{mt, t, ParamTy};
-use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region,
- ReEmpty};
+use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region, ReEmpty};
use middle::ty::{ty_bool, ty_char, ty_bot, ty_box, ty_struct, ty_enum};
use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn, ty_closure};
use middle::ty::{ty_nil, ty_param, ty_ptr, ty_rptr, ty_tup};
BrFresh(_) => "an anonymous lifetime defined on".to_string(),
_ => {
format!("the lifetime {} as defined on",
- bound_region_ptr_to_str(cx, fr.bound_region))
+ bound_region_ptr_to_string(cx, fr.bound_region))
}
};
}
}
-pub fn bound_region_ptr_to_str(cx: &ctxt, br: BoundRegion) -> String {
- bound_region_to_str(cx, "", false, br)
+pub fn bound_region_ptr_to_string(cx: &ctxt, br: BoundRegion) -> String {
+ bound_region_to_string(cx, "", false, br)
}
-pub fn bound_region_to_str(cx: &ctxt,
+pub fn bound_region_to_string(cx: &ctxt,
prefix: &str, space: bool,
br: BoundRegion) -> String {
let space_str = if space { " " } else { "" };
// In general, if you are giving a region error message,
// you should use `explain_region()` or, better yet,
// `note_and_explain_region()`
-pub fn region_ptr_to_str(cx: &ctxt, region: Region) -> String {
- region_to_str(cx, "&", true, region)
+pub fn region_ptr_to_string(cx: &ctxt, region: Region) -> String {
+ region_to_string(cx, "&", true, region)
}
-pub fn region_to_str(cx: &ctxt, prefix: &str, space: bool, region: Region) -> String {
+pub fn region_to_string(cx: &ctxt, prefix: &str, space: bool, region: Region) -> String {
let space_str = if space { " " } else { "" };
if cx.sess.verbose() {
ty::ReEarlyBound(_, _, _, name) => {
token::get_name(name).get().to_string()
}
- ty::ReLateBound(_, br) => bound_region_to_str(cx, prefix, space, br),
- ty::ReFree(ref fr) => bound_region_to_str(cx, prefix, space, fr.bound_region),
+ ty::ReLateBound(_, br) => bound_region_to_string(cx, prefix, space, br),
+ ty::ReFree(ref fr) => bound_region_to_string(cx, prefix, space, fr.bound_region),
ty::ReInfer(ReSkolemized(_, br)) => {
- bound_region_to_str(cx, prefix, space, br)
+ bound_region_to_string(cx, prefix, space, br)
}
ty::ReInfer(ReVar(_)) => prefix.to_string(),
ty::ReStatic => format!("{}'static{}", prefix, space_str),
}
}
-pub fn mutability_to_str(m: ast::Mutability) -> String {
+pub fn mutability_to_string(m: ast::Mutability) -> String {
match m {
ast::MutMutable => "mut ".to_string(),
ast::MutImmutable => "".to_string(),
}
}
-pub fn mt_to_str(cx: &ctxt, m: &mt) -> String {
- format!("{}{}", mutability_to_str(m.mutbl), ty_to_str(cx, m.ty))
+pub fn mt_to_string(cx: &ctxt, m: &mt) -> String {
+ format!("{}{}", mutability_to_string(m.mutbl), ty_to_string(cx, m.ty))
}
-pub fn trait_store_to_str(cx: &ctxt, s: ty::TraitStore) -> String {
+pub fn trait_store_to_string(cx: &ctxt, s: ty::TraitStore) -> String {
match s {
ty::UniqTraitStore => "Box ".to_string(),
ty::RegionTraitStore(r, m) => {
- format!("{}{}", region_ptr_to_str(cx, r), mutability_to_str(m))
+ format!("{}{}", region_ptr_to_string(cx, r), mutability_to_string(m))
}
}
}
-pub fn vec_map_to_str<T>(ts: &[T], f: |t: &T| -> String) -> String {
+pub fn vec_map_to_string<T>(ts: &[T], f: |t: &T| -> String) -> String {
let tstrs = ts.iter().map(f).collect::<Vec<String>>();
format!("[{}]", tstrs.connect(", "))
}
-pub fn fn_sig_to_str(cx: &ctxt, typ: &ty::FnSig) -> String {
+pub fn fn_sig_to_string(cx: &ctxt, typ: &ty::FnSig) -> String {
format!("fn{}{} -> {}", typ.binder_id, typ.inputs.repr(cx),
typ.output.repr(cx))
}
-pub fn trait_ref_to_str(cx: &ctxt, trait_ref: &ty::TraitRef) -> String {
+pub fn trait_ref_to_string(cx: &ctxt, trait_ref: &ty::TraitRef) -> String {
trait_ref.user_string(cx).to_string()
}
-pub fn ty_to_str(cx: &ctxt, typ: t) -> String {
- fn fn_input_to_str(cx: &ctxt, input: ty::t) -> String {
- ty_to_str(cx, input).to_string()
+pub fn ty_to_string(cx: &ctxt, typ: t) -> String {
+ fn fn_input_to_string(cx: &ctxt, input: ty::t) -> String {
+ ty_to_string(cx, input).to_string()
}
- fn bare_fn_to_str(cx: &ctxt,
+ fn bare_fn_to_string(cx: &ctxt,
fn_style: ast::FnStyle,
abi: abi::Abi,
ident: Option<ast::Ident>,
match fn_style {
ast::NormalFn => {}
_ => {
- s.push_str(fn_style.to_str().as_slice());
+ s.push_str(fn_style.to_string().as_slice());
s.push_char(' ');
}
};
if abi != abi::Rust {
- s.push_str(format!("extern {} ", abi.to_str()).as_slice());
+ s.push_str(format!("extern {} ", abi.to_string()).as_slice());
};
s.push_str("fn");
_ => { }
}
- push_sig_to_str(cx, &mut s, '(', ')', sig);
+ push_sig_to_string(cx, &mut s, '(', ')', sig);
s
}
- fn closure_to_str(cx: &ctxt, cty: &ty::ClosureTy) -> String {
+ fn closure_to_string(cx: &ctxt, cty: &ty::ClosureTy) -> String {
let mut s = String::new();
match cty.store {
ty::UniqTraitStore => {}
ty::RegionTraitStore(region, _) => {
- s.push_str(region_to_str(cx, "", true, region).as_slice());
+ s.push_str(region_to_string(cx, "", true, region).as_slice());
}
}
match cty.fn_style {
ast::NormalFn => {}
_ => {
- s.push_str(cty.fn_style.to_str().as_slice());
+ s.push_str(cty.fn_style.to_string().as_slice());
s.push_char(' ');
}
};
ty::UniqTraitStore => {
assert_eq!(cty.onceness, ast::Once);
s.push_str("proc");
- push_sig_to_str(cx, &mut s, '(', ')', &cty.sig);
+ push_sig_to_string(cx, &mut s, '(', ')', &cty.sig);
}
ty::RegionTraitStore(..) => {
match cty.onceness {
ast::Many => {}
ast::Once => s.push_str("once ")
}
- push_sig_to_str(cx, &mut s, '|', '|', &cty.sig);
+ push_sig_to_string(cx, &mut s, '|', '|', &cty.sig);
}
}
s
}
- fn push_sig_to_str(cx: &ctxt,
+ fn push_sig_to_string(cx: &ctxt,
s: &mut String,
bra: char,
ket: char,
sig: &ty::FnSig) {
s.push_char(bra);
- let strs: Vec<String> = sig.inputs.iter().map(|a| fn_input_to_str(cx, *a)).collect();
+ let strs: Vec<String> = sig.inputs.iter().map(|a| fn_input_to_string(cx, *a)).collect();
s.push_str(strs.connect(", ").as_slice());
if sig.variadic {
s.push_str(", ...");
if ty::type_is_bot(sig.output) {
s.push_char('!');
} else {
- s.push_str(ty_to_str(cx, sig.output).as_slice());
+ s.push_str(ty_to_string(cx, sig.output).as_slice());
}
}
}
ty_bot => "!".to_string(),
ty_bool => "bool".to_string(),
ty_char => "char".to_string(),
- ty_int(t) => ast_util::int_ty_to_str(t, None).to_string(),
- ty_uint(t) => ast_util::uint_ty_to_str(t, None).to_string(),
- ty_float(t) => ast_util::float_ty_to_str(t).to_string(),
- ty_box(typ) => format!("Gc<{}>", ty_to_str(cx, typ)),
- ty_uniq(typ) => format!("Box<{}>", ty_to_str(cx, typ)),
+ ty_int(t) => ast_util::int_ty_to_string(t, None).to_string(),
+ ty_uint(t) => ast_util::uint_ty_to_string(t, None).to_string(),
+ ty_float(t) => ast_util::float_ty_to_string(t).to_string(),
+ ty_box(typ) => format!("Gc<{}>", ty_to_string(cx, typ)),
+ ty_uniq(typ) => format!("Box<{}>", ty_to_string(cx, typ)),
ty_ptr(ref tm) => {
format!("*{} {}", match tm.mutbl {
ast::MutMutable => "mut",
ast::MutImmutable => "const",
- }, ty_to_str(cx, tm.ty))
+ }, ty_to_string(cx, tm.ty))
}
ty_rptr(r, ref tm) => {
- let mut buf = region_ptr_to_str(cx, r);
- buf.push_str(mt_to_str(cx, tm).as_slice());
+ let mut buf = region_ptr_to_string(cx, r);
+ buf.push_str(mt_to_string(cx, tm).as_slice());
buf
}
ty_tup(ref elems) => {
- let strs: Vec<String> = elems.iter().map(|elem| ty_to_str(cx, *elem)).collect();
+ let strs: Vec<String> = elems.iter().map(|elem| ty_to_string(cx, *elem)).collect();
format!("({})", strs.connect(","))
}
ty_closure(ref f) => {
- closure_to_str(cx, *f)
+ closure_to_string(cx, *f)
}
ty_bare_fn(ref f) => {
- bare_fn_to_str(cx, f.fn_style, f.abi, None, &f.sig)
+ bare_fn_to_string(cx, f.fn_style, f.abi, None, &f.sig)
}
- ty_infer(infer_ty) => infer_ty.to_str(),
+ ty_infer(infer_ty) => infer_ty.to_string(),
ty_err => "[type error]".to_string(),
ty_param(ParamTy {idx: id, def_id: did, ..}) => {
let ident = match cx.ty_param_defs.borrow().find(&did.node) {
ty_vec(ref mt, sz) => {
match sz {
Some(n) => {
- format!("[{}, .. {}]", mt_to_str(cx, mt), n)
+ format!("[{}, .. {}]", mt_to_string(cx, mt), n)
}
- None => format!("[{}]", ty_to_str(cx, mt.ty)),
+ None => format!("[{}]", ty_to_string(cx, mt.ty)),
}
}
}
subst::ErasedRegions => { }
subst::NonerasedRegions(ref regions) => {
for &r in regions.iter() {
- let s = region_to_str(cx, "", false, r);
+ let s = region_to_string(cx, "", false, r);
if !s.is_empty() {
strs.push(s)
} else {
}
}
- let tps = substs.types.get_vec(subst::TypeSpace);
- let ty_params = generics.types.get_vec(subst::TypeSpace);
+ let tps = substs.types.get_slice(subst::TypeSpace);
+ let ty_params = generics.types.get_slice(subst::TypeSpace);
let has_defaults = ty_params.last().map_or(false, |def| def.default.is_some());
let num_defaults = if has_defaults && !cx.sess.verbose() {
ty_params.iter().zip(tps.iter()).rev().take_while(|&(def, &actual)| {
};
for t in tps.slice_to(tps.len() - num_defaults).iter() {
- strs.push(ty_to_str(cx, *t))
+ strs.push(ty_to_string(cx, *t))
}
if cx.sess.verbose() {
- for t in substs.types.get_vec(subst::SelfSpace).iter() {
+ for t in substs.types.get_slice(subst::SelfSpace).iter() {
strs.push(format!("for {}", t.repr(cx)));
}
}
}
fn repr_vec<T:Repr>(tcx: &ctxt, v: &[T]) -> String {
- vec_map_to_str(v, |t| t.repr(tcx))
+ vec_map_to_string(v, |t| t.repr(tcx))
}
impl<'a, T:Repr> Repr for &'a [T] {
impl Repr for ty::t {
fn repr(&self, tcx: &ctxt) -> String {
- ty_to_str(tcx, *self)
+ ty_to_string(tcx, *self)
}
}
impl Repr for ty::mt {
fn repr(&self, tcx: &ctxt) -> String {
- mt_to_str(tcx, self)
+ mt_to_string(tcx, self)
}
}
impl<T:Repr> Repr for subst::VecPerParamSpace<T> {
fn repr(&self, tcx: &ctxt) -> String {
format!("[{};{};{}]",
- self.get_vec(subst::TypeSpace).repr(tcx),
- self.get_vec(subst::SelfSpace).repr(tcx),
- self.get_vec(subst::FnSpace).repr(tcx))
+ self.get_slice(subst::TypeSpace).repr(tcx),
+ self.get_slice(subst::SelfSpace).repr(tcx),
+ self.get_slice(subst::FnSpace).repr(tcx))
}
}
impl Repr for ty::TraitRef {
fn repr(&self, tcx: &ctxt) -> String {
- trait_ref_to_str(tcx, self)
+ trait_ref_to_string(tcx, self)
}
}
impl Repr for ast::Expr {
fn repr(&self, _tcx: &ctxt) -> String {
- format!("expr({}: {})", self.id, pprust::expr_to_str(self))
+ format!("expr({}: {})", self.id, pprust::expr_to_string(self))
}
}
impl Repr for ast::Path {
fn repr(&self, _tcx: &ctxt) -> String {
- format!("path({})", pprust::path_to_str(self))
+ format!("path({})", pprust::path_to_string(self))
}
}
impl Repr for ast::Item {
fn repr(&self, tcx: &ctxt) -> String {
- format!("item({})", tcx.map.node_to_str(self.id))
+ format!("item({})", tcx.map.node_to_string(self.id))
}
}
fn repr(&self, _tcx: &ctxt) -> String {
format!("stmt({}: {})",
ast_util::stmt_id(self),
- pprust::stmt_to_str(self))
+ pprust::stmt_to_string(self))
}
}
impl Repr for ast::Pat {
fn repr(&self, _tcx: &ctxt) -> String {
- format!("pat({}: {})", self.id, pprust::pat_to_str(self))
+ format!("pat({}: {})", self.id, pprust::pat_to_string(self))
}
}
impl Repr for ty::Variance {
fn repr(&self, _: &ctxt) -> String {
- // The first `.to_str()` returns a &'static str (it is not an implementation
- // of the ToStr trait). Because of that, we need to call `.to_str()` again
+ // The first `.to_string()` returns a &'static str (it is not an implementation
+ // of the ToString trait). Because of that, we need to call `.to_string()` again
// if we want to have a `String`.
- self.to_str().to_str()
+ self.to_string().to_string()
}
}
fn repr(&self, tcx: &ctxt) -> String {
format!("BareFnTy {{fn_style: {:?}, abi: {}, sig: {}}}",
self.fn_style,
- self.abi.to_str(),
+ self.abi.to_string(),
self.sig.repr(tcx))
}
}
impl Repr for ty::FnSig {
fn repr(&self, tcx: &ctxt) -> String {
- fn_sig_to_str(tcx, self)
+ fn_sig_to_string(tcx, self)
}
}
impl Repr for ty::TraitStore {
fn repr(&self, tcx: &ctxt) -> String {
- trait_store_to_str(tcx, *self)
+ trait_store_to_string(tcx, *self)
}
}
impl Repr for Span {
fn repr(&self, tcx: &ctxt) -> String {
- tcx.sess.codemap().span_to_str(*self).to_string()
+ tcx.sess.codemap().span_to_string(*self).to_string()
}
}
impl UserString for ty::t {
fn user_string(&self, tcx: &ctxt) -> String {
- ty_to_str(tcx, *self)
+ ty_to_string(tcx, *self)
}
}
impl Repr for abi::Abi {
fn repr(&self, _tcx: &ctxt) -> String {
- self.to_str()
+ self.to_string()
}
}
impl UserString for abi::Abi {
fn user_string(&self, _tcx: &ctxt) -> String {
- self.to_str()
+ self.to_string()
}
}
+++ /dev/null
-// Copyright 2012-2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! This module implements only the Sha256 function since that is all that is needed for internal
-//! use. This implementation is not intended for external use or for any use where security is
-//! important.
-
-use std::iter::range_step;
-use std::num::Zero;
-use std::slice::bytes::{MutableByteVector, copy_memory};
-use serialize::hex::ToHex;
-
-/// Write a u32 into a vector, which must be 4 bytes long. The value is written in big-endian
-/// format.
-fn write_u32_be(dst: &mut[u8], input: u32) {
- use std::mem::to_be32;
- assert!(dst.len() == 4);
- unsafe {
- let x = dst.unsafe_mut_ref(0) as *mut _ as *mut u32;
- *x = to_be32(input);
- }
-}
-
-/// Read a vector of bytes into a vector of u32s. The values are read in big-endian format.
-fn read_u32v_be(dst: &mut[u32], input: &[u8]) {
- use std::mem::to_be32;
- assert!(dst.len() * 4 == input.len());
- unsafe {
- let mut x = dst.unsafe_mut_ref(0) as *mut _ as *mut u32;
- let mut y = input.unsafe_ref(0) as *const _ as *const u32;
- for _ in range(0, dst.len()) {
- *x = to_be32(*y);
- x = x.offset(1);
- y = y.offset(1);
- }
- }
-}
-
-trait ToBits {
- /// Convert the value in bytes to the number of bits, a tuple where the 1st item is the
- /// high-order value and the 2nd item is the low order value.
- fn to_bits(self) -> (Self, Self);
-}
-
-impl ToBits for u64 {
- fn to_bits(self) -> (u64, u64) {
- return (self >> 61, self << 3);
- }
-}
-
-/// Adds the specified number of bytes to the bit count. fail!() if this would cause numeric
-/// overflow.
-fn add_bytes_to_bits<T: Int + CheckedAdd + ToBits>(bits: T, bytes: T) -> T {
- let (new_high_bits, new_low_bits) = bytes.to_bits();
-
- if new_high_bits > Zero::zero() {
- fail!("numeric overflow occurred.")
- }
-
- match bits.checked_add(&new_low_bits) {
- Some(x) => return x,
- None => fail!("numeric overflow occurred.")
- }
-}
-
-/// A FixedBuffer, likes its name implies, is a fixed size buffer. When the buffer becomes full, it
-/// must be processed. The input() method takes care of processing and then clearing the buffer
-/// automatically. However, other methods do not and require the caller to process the buffer. Any
-/// method that modifies the buffer directory or provides the caller with bytes that can be modified
-/// results in those bytes being marked as used by the buffer.
-trait FixedBuffer {
- /// Input a vector of bytes. If the buffer becomes full, process it with the provided
- /// function and then clear the buffer.
- fn input(&mut self, input: &[u8], func: |&[u8]|);
-
- /// Reset the buffer.
- fn reset(&mut self);
-
- /// Zero the buffer up until the specified index. The buffer position currently must not be
- /// greater than that index.
- fn zero_until(&mut self, idx: uint);
-
- /// Get a slice of the buffer of the specified size. There must be at least that many bytes
- /// remaining in the buffer.
- fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8];
-
- /// Get the current buffer. The buffer must already be full. This clears the buffer as well.
- fn full_buffer<'s>(&'s mut self) -> &'s [u8];
-
- /// Get the current position of the buffer.
- fn position(&self) -> uint;
-
- /// Get the number of bytes remaining in the buffer until it is full.
- fn remaining(&self) -> uint;
-
- /// Get the size of the buffer
- fn size(&self) -> uint;
-}
-
-/// A FixedBuffer of 64 bytes useful for implementing Sha256 which has a 64 byte blocksize.
-struct FixedBuffer64 {
- buffer: [u8, ..64],
- buffer_idx: uint,
-}
-
-impl FixedBuffer64 {
- /// Create a new FixedBuffer64
- fn new() -> FixedBuffer64 {
- return FixedBuffer64 {
- buffer: [0u8, ..64],
- buffer_idx: 0
- };
- }
-}
-
-impl FixedBuffer for FixedBuffer64 {
- fn input(&mut self, input: &[u8], func: |&[u8]|) {
- let mut i = 0;
-
- let size = self.size();
-
- // If there is already data in the buffer, copy as much as we can into it and process
- // the data if the buffer becomes full.
- if self.buffer_idx != 0 {
- let buffer_remaining = size - self.buffer_idx;
- if input.len() >= buffer_remaining {
- copy_memory(
- self.buffer.mut_slice(self.buffer_idx, size),
- input.slice_to(buffer_remaining));
- self.buffer_idx = 0;
- func(self.buffer);
- i += buffer_remaining;
- } else {
- copy_memory(
- self.buffer.mut_slice(self.buffer_idx, self.buffer_idx + input.len()),
- input);
- self.buffer_idx += input.len();
- return;
- }
- }
-
- // While we have at least a full buffer size chunk's worth of data, process that data
- // without copying it into the buffer
- while input.len() - i >= size {
- func(input.slice(i, i + size));
- i += size;
- }
-
- // Copy any input data into the buffer. At this point in the method, the amount of
- // data left in the input vector will be less than the buffer size and the buffer will
- // be empty.
- let input_remaining = input.len() - i;
- copy_memory(
- self.buffer.mut_slice(0, input_remaining),
- input.slice_from(i));
- self.buffer_idx += input_remaining;
- }
-
- fn reset(&mut self) {
- self.buffer_idx = 0;
- }
-
- fn zero_until(&mut self, idx: uint) {
- assert!(idx >= self.buffer_idx);
- self.buffer.mut_slice(self.buffer_idx, idx).set_memory(0);
- self.buffer_idx = idx;
- }
-
- fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8] {
- self.buffer_idx += len;
- return self.buffer.mut_slice(self.buffer_idx - len, self.buffer_idx);
- }
-
- fn full_buffer<'s>(&'s mut self) -> &'s [u8] {
- assert!(self.buffer_idx == 64);
- self.buffer_idx = 0;
- return self.buffer.slice_to(64);
- }
-
- fn position(&self) -> uint { self.buffer_idx }
-
- fn remaining(&self) -> uint { 64 - self.buffer_idx }
-
- fn size(&self) -> uint { 64 }
-}
-
-/// The StandardPadding trait adds a method useful for Sha256 to a FixedBuffer struct.
-trait StandardPadding {
- /// Add padding to the buffer. The buffer must not be full when this method is called and is
- /// guaranteed to have exactly rem remaining bytes when it returns. If there are not at least
- /// rem bytes available, the buffer will be zero padded, processed, cleared, and then filled
- /// with zeros again until only rem bytes are remaining.
- fn standard_padding(&mut self, rem: uint, func: |&[u8]|);
-}
-
-impl <T: FixedBuffer> StandardPadding for T {
- fn standard_padding(&mut self, rem: uint, func: |&[u8]|) {
- let size = self.size();
-
- self.next(1)[0] = 128;
-
- if self.remaining() < rem {
- self.zero_until(size);
- func(self.full_buffer());
- }
-
- self.zero_until(size - rem);
- }
-}
-
-/// The Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2
-/// family of digest functions.
-pub trait Digest {
- /// Provide message data.
- ///
- /// # Arguments
- ///
- /// * input - A vector of message data
- fn input(&mut self, input: &[u8]);
-
- /// Retrieve the digest result. This method may be called multiple times.
- ///
- /// # Arguments
- ///
- /// * out - the vector to hold the result. Must be large enough to contain output_bits().
- fn result(&mut self, out: &mut [u8]);
-
- /// Reset the digest. This method must be called after result() and before supplying more
- /// data.
- fn reset(&mut self);
-
- /// Get the output size in bits.
- fn output_bits(&self) -> uint;
-
- /// Convenience function that feeds a string into a digest.
- ///
- /// # Arguments
- ///
- /// * `input` The string to feed into the digest
- fn input_str(&mut self, input: &str) {
- self.input(input.as_bytes());
- }
-
- /// Convenience function that retrieves the result of a digest as a
- /// newly allocated vec of bytes.
- fn result_bytes(&mut self) -> Vec<u8> {
- let mut buf = Vec::from_elem((self.output_bits()+7)/8, 0u8);
- self.result(buf.as_mut_slice());
- buf
- }
-
- /// Convenience function that retrieves the result of a digest as a
- /// String in hexadecimal format.
- fn result_str(&mut self) -> String {
- self.result_bytes().as_slice().to_hex().to_string()
- }
-}
-
-// A structure that represents that state of a digest computation for the SHA-2 512 family of digest
-// functions
-struct Engine256State {
- h0: u32,
- h1: u32,
- h2: u32,
- h3: u32,
- h4: u32,
- h5: u32,
- h6: u32,
- h7: u32,
-}
-
-impl Engine256State {
- fn new(h: &[u32, ..8]) -> Engine256State {
- return Engine256State {
- h0: h[0],
- h1: h[1],
- h2: h[2],
- h3: h[3],
- h4: h[4],
- h5: h[5],
- h6: h[6],
- h7: h[7]
- };
- }
-
- fn reset(&mut self, h: &[u32, ..8]) {
- self.h0 = h[0];
- self.h1 = h[1];
- self.h2 = h[2];
- self.h3 = h[3];
- self.h4 = h[4];
- self.h5 = h[5];
- self.h6 = h[6];
- self.h7 = h[7];
- }
-
- fn process_block(&mut self, data: &[u8]) {
- fn ch(x: u32, y: u32, z: u32) -> u32 {
- ((x & y) ^ ((!x) & z))
- }
-
- fn maj(x: u32, y: u32, z: u32) -> u32 {
- ((x & y) ^ (x & z) ^ (y & z))
- }
-
- fn sum0(x: u32) -> u32 {
- ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10))
- }
-
- fn sum1(x: u32) -> u32 {
- ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7))
- }
-
- fn sigma0(x: u32) -> u32 {
- ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3)
- }
-
- fn sigma1(x: u32) -> u32 {
- ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10)
- }
-
- let mut a = self.h0;
- let mut b = self.h1;
- let mut c = self.h2;
- let mut d = self.h3;
- let mut e = self.h4;
- let mut f = self.h5;
- let mut g = self.h6;
- let mut h = self.h7;
-
- let mut w = [0u32, ..64];
-
- // Sha-512 and Sha-256 use basically the same calculations which are implemented
- // by these macros. Inlining the calculations seems to result in better generated code.
- macro_rules! schedule_round( ($t:expr) => (
- w[$t] = sigma1(w[$t - 2]) + w[$t - 7] + sigma0(w[$t - 15]) + w[$t - 16];
- )
- )
-
- macro_rules! sha2_round(
- ($A:ident, $B:ident, $C:ident, $D:ident,
- $E:ident, $F:ident, $G:ident, $H:ident, $K:ident, $t:expr) => (
- {
- $H += sum1($E) + ch($E, $F, $G) + $K[$t] + w[$t];
- $D += $H;
- $H += sum0($A) + maj($A, $B, $C);
- }
- )
- )
-
- read_u32v_be(w.mut_slice(0, 16), data);
-
- // Putting the message schedule inside the same loop as the round calculations allows for
- // the compiler to generate better code.
- for t in range_step(0u, 48, 8) {
- schedule_round!(t + 16);
- schedule_round!(t + 17);
- schedule_round!(t + 18);
- schedule_round!(t + 19);
- schedule_round!(t + 20);
- schedule_round!(t + 21);
- schedule_round!(t + 22);
- schedule_round!(t + 23);
-
- sha2_round!(a, b, c, d, e, f, g, h, K32, t);
- sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
- sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
- sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3);
- sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4);
- sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
- sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
- sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
- }
-
- for t in range_step(48u, 64, 8) {
- sha2_round!(a, b, c, d, e, f, g, h, K32, t);
- sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
- sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
- sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3);
- sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4);
- sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
- sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
- sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
- }
-
- self.h0 += a;
- self.h1 += b;
- self.h2 += c;
- self.h3 += d;
- self.h4 += e;
- self.h5 += f;
- self.h6 += g;
- self.h7 += h;
- }
-}
-
-static K32: [u32, ..64] = [
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
- 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
- 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
- 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
- 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
- 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
- 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
- 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
- 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-];
-
-// A structure that keeps track of the state of the Sha-256 operation and contains the logic
-// necessary to perform the final calculations.
-struct Engine256 {
- length_bits: u64,
- buffer: FixedBuffer64,
- state: Engine256State,
- finished: bool,
-}
-
-impl Engine256 {
- fn new(h: &[u32, ..8]) -> Engine256 {
- return Engine256 {
- length_bits: 0,
- buffer: FixedBuffer64::new(),
- state: Engine256State::new(h),
- finished: false
- }
- }
-
- fn reset(&mut self, h: &[u32, ..8]) {
- self.length_bits = 0;
- self.buffer.reset();
- self.state.reset(h);
- self.finished = false;
- }
-
- fn input(&mut self, input: &[u8]) {
- assert!(!self.finished)
- // Assumes that input.len() can be converted to u64 without overflow
- self.length_bits = add_bytes_to_bits(self.length_bits, input.len() as u64);
- let self_state = &mut self.state;
- self.buffer.input(input, |input: &[u8]| { self_state.process_block(input) });
- }
-
- fn finish(&mut self) {
- if self.finished {
- return;
- }
-
- let self_state = &mut self.state;
- self.buffer.standard_padding(8, |input: &[u8]| { self_state.process_block(input) });
- write_u32_be(self.buffer.next(4), (self.length_bits >> 32) as u32 );
- write_u32_be(self.buffer.next(4), self.length_bits as u32);
- self_state.process_block(self.buffer.full_buffer());
-
- self.finished = true;
- }
-}
-
-/// The SHA-256 hash algorithm
-pub struct Sha256 {
- engine: Engine256
-}
-
-impl Sha256 {
- /// Construct a new instance of a SHA-256 digest.
- pub fn new() -> Sha256 {
- Sha256 {
- engine: Engine256::new(&H256)
- }
- }
-}
-
-impl Digest for Sha256 {
- fn input(&mut self, d: &[u8]) {
- self.engine.input(d);
- }
-
- fn result(&mut self, out: &mut [u8]) {
- self.engine.finish();
-
- write_u32_be(out.mut_slice(0, 4), self.engine.state.h0);
- write_u32_be(out.mut_slice(4, 8), self.engine.state.h1);
- write_u32_be(out.mut_slice(8, 12), self.engine.state.h2);
- write_u32_be(out.mut_slice(12, 16), self.engine.state.h3);
- write_u32_be(out.mut_slice(16, 20), self.engine.state.h4);
- write_u32_be(out.mut_slice(20, 24), self.engine.state.h5);
- write_u32_be(out.mut_slice(24, 28), self.engine.state.h6);
- write_u32_be(out.mut_slice(28, 32), self.engine.state.h7);
- }
-
- fn reset(&mut self) {
- self.engine.reset(&H256);
- }
-
- fn output_bits(&self) -> uint { 256 }
-}
-
-static H256: [u32, ..8] = [
- 0x6a09e667,
- 0xbb67ae85,
- 0x3c6ef372,
- 0xa54ff53a,
- 0x510e527f,
- 0x9b05688c,
- 0x1f83d9ab,
- 0x5be0cd19
-];
-
-#[cfg(test)]
-mod tests {
- extern crate rand;
-
- use super::{Digest, Sha256, FixedBuffer};
- use std::num::Bounded;
- use self::rand::isaac::IsaacRng;
- use self::rand::Rng;
- use serialize::hex::FromHex;
-
- // A normal addition - no overflow occurs
- #[test]
- fn test_add_bytes_to_bits_ok() {
- assert!(super::add_bytes_to_bits::<u64>(100, 10) == 180);
- }
-
- // A simple failure case - adding 1 to the max value
- #[test]
- #[should_fail]
- fn test_add_bytes_to_bits_overflow() {
- super::add_bytes_to_bits::<u64>(Bounded::max_value(), 1);
- }
-
- struct Test {
- input: String,
- output_str: String,
- }
-
- fn test_hash<D: Digest>(sh: &mut D, tests: &[Test]) {
- // Test that it works when accepting the message all at once
- for t in tests.iter() {
- sh.reset();
- sh.input_str(t.input.as_slice());
- let out_str = sh.result_str();
- assert!(out_str == t.output_str);
- }
-
- // Test that it works when accepting the message in pieces
- for t in tests.iter() {
- sh.reset();
- let len = t.input.len();
- let mut left = len;
- while left > 0u {
- let take = (left + 1u) / 2u;
- sh.input_str(t.input
- .as_slice()
- .slice(len - left, take + len - left));
- left = left - take;
- }
- let out_str = sh.result_str();
- assert!(out_str == t.output_str);
- }
- }
-
- #[test]
- fn test_sha256() {
- // Examples from wikipedia
- let wikipedia_tests = vec!(
- Test {
- input: "".to_string(),
- output_str: "e3b0c44298fc1c149afb\
- f4c8996fb92427ae41e4649b934ca495991b7852b855".to_string()
- },
- Test {
- input: "The quick brown fox jumps over the lazy \
- dog".to_string(),
- output_str: "d7a8fbb307d7809469ca\
- 9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592".to_string()
- },
- Test {
- input: "The quick brown fox jumps over the lazy \
- dog.".to_string(),
- output_str: "ef537f25c895bfa78252\
- 6529a9b63d97aa631564d5d789c2b765448c8635fb6c".to_string()
- });
-
- let tests = wikipedia_tests;
-
- let mut sh = box Sha256::new();
-
- test_hash(&mut *sh, tests.as_slice());
- }
-
- /// Feed 1,000,000 'a's into the digest with varying input sizes and check that the result is
- /// correct.
- fn test_digest_1million_random<D: Digest>(digest: &mut D, blocksize: uint, expected: &str) {
- let total_size = 1000000;
- let buffer = Vec::from_elem(blocksize * 2, 'a' as u8);
- let mut rng = IsaacRng::new_unseeded();
- let mut count = 0;
-
- digest.reset();
-
- while count < total_size {
- let next: uint = rng.gen_range(0, 2 * blocksize + 1);
- let remaining = total_size - count;
- let size = if next > remaining { remaining } else { next };
- digest.input(buffer.slice_to(size));
- count += size;
- }
-
- let result_str = digest.result_str();
- let result_bytes = digest.result_bytes();
-
- assert_eq!(expected, result_str.as_slice());
-
- let expected_vec: Vec<u8> = expected.from_hex()
- .unwrap()
- .move_iter()
- .collect();
- assert_eq!(expected_vec, result_bytes);
- }
-
- #[test]
- fn test_1million_random_sha256() {
- let mut sh = Sha256::new();
- test_digest_1million_random(
- &mut sh,
- 64,
- "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");
- }
-}
-
-#[cfg(test)]
-mod bench {
- extern crate test;
- use self::test::Bencher;
- use super::{Sha256, FixedBuffer, Digest};
-
- #[bench]
- pub fn sha256_10(b: &mut Bencher) {
- let mut sh = Sha256::new();
- let bytes = [1u8, ..10];
- b.iter(|| {
- sh.input(bytes);
- });
- b.bytes = bytes.len() as u64;
- }
-
- #[bench]
- pub fn sha256_1k(b: &mut Bencher) {
- let mut sh = Sha256::new();
- let bytes = [1u8, ..1024];
- b.iter(|| {
- sh.input(bytes);
- });
- b.bytes = bytes.len() as u64;
- }
-
- #[bench]
- pub fn sha256_64k(b: &mut Bencher) {
- let mut sh = Sha256::new();
- let bytes = [1u8, ..65536];
- b.iter(|| {
- sh.input(bytes);
- });
- b.bytes = bytes.len() as u64;
- }
-}
--- /dev/null
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub static box_field_refcnt: uint = 0u;
+pub static box_field_tydesc: uint = 1u;
+pub static box_field_body: uint = 4u;
+
+pub static tydesc_field_visit_glue: uint = 3u;
+
+// The two halves of a closure: code and environment.
+pub static fn_field_code: uint = 0u;
+pub static fn_field_box: uint = 1u;
+
+// The two fields of a trait object/trait instance: vtable and box.
+// The vtable contains the type descriptor as first element.
+pub static trt_field_vtable: uint = 0u;
+pub static trt_field_box: uint = 1u;
+
+pub static vec_elt_fill: uint = 0u;
+
+pub static vec_elt_alloc: uint = 1u;
+
+pub static vec_elt_elems: uint = 2u;
+
+pub static slice_elt_base: uint = 0u;
+pub static slice_elt_len: uint = 1u;
--- /dev/null
+// Copyright 2013-2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A helper class for dealing with static archives
+
+use std::io::process::{Command, ProcessOutput};
+use std::io::{fs, TempDir};
+use std::io;
+use std::os;
+use std::str;
+use syntax::abi;
+use ErrorHandler = syntax::diagnostic::Handler;
+
+pub static METADATA_FILENAME: &'static str = "rust.metadata.bin";
+
+pub struct ArchiveConfig<'a> {
+ pub handler: &'a ErrorHandler,
+ pub dst: Path,
+ pub lib_search_paths: Vec<Path>,
+ pub os: abi::Os,
+ pub maybe_ar_prog: Option<String>
+}
+
+pub struct Archive<'a> {
+ handler: &'a ErrorHandler,
+ dst: Path,
+ lib_search_paths: Vec<Path>,
+ os: abi::Os,
+ maybe_ar_prog: Option<String>
+}
+
+fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
+ args: &str, cwd: Option<&Path>,
+ paths: &[&Path]) -> ProcessOutput {
+ let ar = match *maybe_ar_prog {
+ Some(ref ar) => ar.as_slice(),
+ None => "ar"
+ };
+ let mut cmd = Command::new(ar);
+
+ cmd.arg(args).args(paths);
+ debug!("{}", cmd);
+
+ match cwd {
+ Some(p) => {
+ cmd.cwd(p);
+ debug!("inside {}", p.display());
+ }
+ None => {}
+ }
+
+ match cmd.spawn() {
+ Ok(prog) => {
+ let o = prog.wait_with_output().unwrap();
+ if !o.status.success() {
+ handler.err(format!("{} failed with: {}",
+ cmd,
+ o.status).as_slice());
+ handler.note(format!("stdout ---\n{}",
+ str::from_utf8(o.output
+ .as_slice()).unwrap())
+ .as_slice());
+ handler.note(format!("stderr ---\n{}",
+ str::from_utf8(o.error
+ .as_slice()).unwrap())
+ .as_slice());
+ handler.abort_if_errors();
+ }
+ o
+ },
+ Err(e) => {
+ handler.err(format!("could not exec `{}`: {}", ar.as_slice(),
+ e).as_slice());
+ handler.abort_if_errors();
+ fail!("rustc::back::archive::run_ar() should not reach this point");
+ }
+ }
+}
+
+impl<'a> Archive<'a> {
+ /// Initializes a new static archive with the given object file
+ pub fn create<'b>(config: ArchiveConfig<'a>, initial_object: &'b Path) -> Archive<'a> {
+ let ArchiveConfig { handler, dst, lib_search_paths, os, maybe_ar_prog } = config;
+ run_ar(handler, &maybe_ar_prog, "crus", None, [&dst, initial_object]);
+ Archive {
+ handler: handler,
+ dst: dst,
+ lib_search_paths: lib_search_paths,
+ os: os,
+ maybe_ar_prog: maybe_ar_prog
+ }
+ }
+
+ /// Opens an existing static archive
+ pub fn open(config: ArchiveConfig<'a>) -> Archive<'a> {
+ let ArchiveConfig { handler, dst, lib_search_paths, os, maybe_ar_prog } = config;
+ assert!(dst.exists());
+ Archive {
+ handler: handler,
+ dst: dst,
+ lib_search_paths: lib_search_paths,
+ os: os,
+ maybe_ar_prog: maybe_ar_prog
+ }
+ }
+
+ /// Adds all of the contents of a native library to this archive. This will
+ /// search in the relevant locations for a library named `name`.
+ pub fn add_native_library(&mut self, name: &str) -> io::IoResult<()> {
+ let location = self.find_library(name);
+ self.add_archive(&location, name, [])
+ }
+
+ /// Adds all of the contents of the rlib at the specified path to this
+ /// archive.
+ ///
+ /// This ignores adding the bytecode from the rlib, and if LTO is enabled
+ /// then the object file also isn't added.
+ pub fn add_rlib(&mut self, rlib: &Path, name: &str,
+ lto: bool) -> io::IoResult<()> {
+ let object = format!("{}.o", name);
+ let bytecode = format!("{}.bytecode.deflate", name);
+ let mut ignore = vec!(bytecode.as_slice(), METADATA_FILENAME);
+ if lto {
+ ignore.push(object.as_slice());
+ }
+ self.add_archive(rlib, name, ignore.as_slice())
+ }
+
+ /// Adds an arbitrary file to this archive
+ pub fn add_file(&mut self, file: &Path, has_symbols: bool) {
+ let cmd = if has_symbols {"r"} else {"rS"};
+ run_ar(self.handler, &self.maybe_ar_prog, cmd, None, [&self.dst, file]);
+ }
+
+ /// Removes a file from this archive
+ pub fn remove_file(&mut self, file: &str) {
+ run_ar(self.handler, &self.maybe_ar_prog, "d", None, [&self.dst, &Path::new(file)]);
+ }
+
+ /// Updates all symbols in the archive (runs 'ar s' over it)
+ pub fn update_symbols(&mut self) {
+ run_ar(self.handler, &self.maybe_ar_prog, "s", None, [&self.dst]);
+ }
+
+ /// Lists all files in an archive
+ pub fn files(&self) -> Vec<String> {
+ let output = run_ar(self.handler, &self.maybe_ar_prog, "t", None, [&self.dst]);
+ let output = str::from_utf8(output.output.as_slice()).unwrap();
+ // use lines_any because windows delimits output with `\r\n` instead of
+ // just `\n`
+ output.lines_any().map(|s| s.to_string()).collect()
+ }
+
+ fn add_archive(&mut self, archive: &Path, name: &str,
+ skip: &[&str]) -> io::IoResult<()> {
+ let loc = TempDir::new("rsar").unwrap();
+
+ // First, extract the contents of the archive to a temporary directory
+ let archive = os::make_absolute(archive);
+ run_ar(self.handler, &self.maybe_ar_prog, "x", Some(loc.path()), [&archive]);
+
+ // Next, we must rename all of the inputs to "guaranteed unique names".
+ // The reason for this is that archives are keyed off the name of the
+ // files, so if two files have the same name they will override one
+ // another in the archive (bad).
+ //
+ // We skip any files explicitly desired for skipping, and we also skip
+ // all SYMDEF files as these are just magical placeholders which get
+ // re-created when we make a new archive anyway.
+ let files = try!(fs::readdir(loc.path()));
+ let mut inputs = Vec::new();
+ for file in files.iter() {
+ let filename = file.filename_str().unwrap();
+ if skip.iter().any(|s| *s == filename) { continue }
+ if filename.contains(".SYMDEF") { continue }
+
+ let filename = format!("r-{}-{}", name, filename);
+ // LLDB (as mentioned in back::link) crashes on filenames of exactly
+ // 16 bytes in length. If we're including an object file with
+ // exactly 16-bytes of characters, give it some prefix so that it's
+ // not 16 bytes.
+ let filename = if filename.len() == 16 {
+ format!("lldb-fix-{}", filename)
+ } else {
+ filename
+ };
+ let new_filename = file.with_filename(filename);
+ try!(fs::rename(file, &new_filename));
+ inputs.push(new_filename);
+ }
+ if inputs.len() == 0 { return Ok(()) }
+
+ // Finally, add all the renamed files to this archive
+ let mut args = vec!(&self.dst);
+ args.extend(inputs.iter());
+ run_ar(self.handler, &self.maybe_ar_prog, "r", None, args.as_slice());
+ Ok(())
+ }
+
+ fn find_library(&self, name: &str) -> Path {
+ let (osprefix, osext) = match self.os {
+ abi::OsWin32 => ("", "lib"), _ => ("lib", "a"),
+ };
+ // On Windows, static libraries sometimes show up as libfoo.a and other
+ // times show up as foo.lib
+ let oslibname = format!("{}{}.{}", osprefix, name, osext);
+ let unixlibname = format!("lib{}.a", name);
+
+ for path in self.lib_search_paths.iter() {
+ debug!("looking for {} inside {}", name, path.display());
+ let test = path.join(oslibname.as_slice());
+ if test.exists() { return test }
+ if oslibname != unixlibname {
+ let test = path.join(unixlibname.as_slice());
+ if test.exists() { return test }
+ }
+ }
+ self.handler.fatal(format!("could not find native static library `{}`, \
+ perhaps an -L flag is missing?",
+ name).as_slice());
+ }
+}
+
--- /dev/null
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use target_strs;
+use syntax::abi;
+
+pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
+ let cc_args = if target_triple.as_slice().contains("thumb") {
+ vec!("-mthumb".to_string())
+ } else {
+ vec!("-marm".to_string())
+ };
+ return target_strs::t {
+ module_asm: "".to_string(),
+
+ data_layout: match target_os {
+ abi::OsMacos => {
+ "e-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+
+ abi::OsiOS => {
+ "e-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+
+ abi::OsWin32 => {
+ "e-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+
+ abi::OsLinux => {
+ "e-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+
+ abi::OsAndroid => {
+ "e-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+
+ abi::OsFreebsd => {
+ "e-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+ },
+
+ target_triple: target_triple,
+
+ cc_args: cc_args,
+ };
+}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::io;
+use std::io::fs;
+use std::os;
+
+/// Returns an absolute path in the filesystem that `path` points to. The
+/// returned path does not contain any symlinks in its hierarchy.
+pub fn realpath(original: &Path) -> io::IoResult<Path> {
+ static MAX_LINKS_FOLLOWED: uint = 256;
+ let original = os::make_absolute(original);
+
+ // Right now lstat on windows doesn't work quite well
+ if cfg!(windows) {
+ return Ok(original)
+ }
+
+ let result = original.root_path();
+ let mut result = result.expect("make_absolute has no root_path");
+ let mut followed = 0;
+
+ for part in original.components() {
+ result.push(part);
+
+ loop {
+ if followed == MAX_LINKS_FOLLOWED {
+ return Err(io::standard_error(io::InvalidInput))
+ }
+
+ match fs::lstat(&result) {
+ Err(..) => break,
+ Ok(ref stat) if stat.kind != io::TypeSymlink => break,
+ Ok(..) => {
+ followed += 1;
+ let path = try!(fs::readlink(&result));
+ result.pop();
+ result.push(path);
+ }
+ }
+ }
+ }
+
+ return Ok(result);
+}
+
+#[cfg(not(windows), test)]
+mod test {
+ use std::io;
+ use std::io::fs::{File, symlink, mkdir, mkdir_recursive};
+ use super::realpath;
+ use std::io::TempDir;
+
+ #[test]
+ fn realpath_works() {
+ let tmpdir = TempDir::new("rustc-fs").unwrap();
+ let tmpdir = realpath(tmpdir.path()).unwrap();
+ let file = tmpdir.join("test");
+ let dir = tmpdir.join("test2");
+ let link = dir.join("link");
+ let linkdir = tmpdir.join("test3");
+
+ File::create(&file).unwrap();
+ mkdir(&dir, io::UserRWX).unwrap();
+ symlink(&file, &link).unwrap();
+ symlink(&dir, &linkdir).unwrap();
+
+ assert!(realpath(&tmpdir).unwrap() == tmpdir);
+ assert!(realpath(&file).unwrap() == file);
+ assert!(realpath(&link).unwrap() == file);
+ assert!(realpath(&linkdir).unwrap() == dir);
+ assert!(realpath(&linkdir.join("link")).unwrap() == file);
+ }
+
+ #[test]
+ fn realpath_works_tricky() {
+ let tmpdir = TempDir::new("rustc-fs").unwrap();
+ let tmpdir = realpath(tmpdir.path()).unwrap();
+
+ let a = tmpdir.join("a");
+ let b = a.join("b");
+ let c = b.join("c");
+ let d = a.join("d");
+ let e = d.join("e");
+ let f = a.join("f");
+
+ mkdir_recursive(&b, io::UserRWX).unwrap();
+ mkdir_recursive(&d, io::UserRWX).unwrap();
+ File::create(&f).unwrap();
+ symlink(&Path::new("../d/e"), &c).unwrap();
+ symlink(&Path::new("../f"), &e).unwrap();
+
+ assert!(realpath(&c).unwrap() == f);
+ assert!(realpath(&e).unwrap() == f);
+ }
+}
--- /dev/null
+// Copyright 2012-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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Some stuff used by rustc that doesn't have many dependencies
+//!
+//! Originally extracted from rustc::back, which was nominally the
+//! compiler 'backend', though LLVM is rustc's backend, so rustc_back
+//! is really just odds-and-ends relating to code gen and linking.
+//! This crate mostly exists to make rustc smaller, so we might put
+//! more 'stuff' here in the future. It does not have a dependency on
+//! rustc_llvm.
+//!
+//! FIXME: Split this into two crates: one that has deps on syntax, and
+//! one that doesn't; the one that doesn't might get decent parallel
+//! build speedups.
+
+#![crate_id = "rustc_back#0.11.0-pre"]
+#![crate_name = "rustc_back"]
+#![experimental]
+#![comment = "The Rust compiler minimal-dependency dumping-ground"]
+#![license = "MIT/ASL2"]
+#![crate_type = "dylib"]
+#![crate_type = "rlib"]
+#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+ html_favicon_url = "http://www.rust-lang.org/favicon.ico",
+ html_root_url = "http://doc.rust-lang.org/")]
+
+#![feature(globs, phase, macro_rules)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
+
+#[phase(plugin, link)]
+extern crate log;
+extern crate syntax;
+extern crate libc;
+extern crate flate;
+extern crate serialize;
+
+pub mod abi;
+pub mod archive;
+pub mod arm;
+pub mod fs;
+pub mod mips;
+pub mod mipsel;
+pub mod rpath;
+pub mod sha2;
+pub mod svh;
+pub mod target_strs;
+pub mod x86;
+pub mod x86_64;
--- /dev/null
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use target_strs;
+use syntax::abi;
+
+pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
+ return target_strs::t {
+ module_asm: "".to_string(),
+
+ data_layout: match target_os {
+ abi::OsMacos => {
+ "E-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+
+ abi::OsiOS => {
+ "E-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+
+ abi::OsWin32 => {
+ "E-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+
+ abi::OsLinux => {
+ "E-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+
+ abi::OsAndroid => {
+ "E-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+
+ abi::OsFreebsd => {
+ "E-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+ },
+
+ target_triple: target_triple,
+
+ cc_args: Vec::new(),
+ };
+}
--- /dev/null
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use target_strs;
+use syntax::abi;
+
+pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
+ return target_strs::t {
+ module_asm: "".to_string(),
+
+ data_layout: match target_os {
+ abi::OsMacos => {
+ "e-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+
+ abi::OsiOS => {
+ "e-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+
+ abi::OsWin32 => {
+ "e-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+
+ abi::OsLinux => {
+ "e-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+
+ abi::OsAndroid => {
+ "e-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+
+ abi::OsFreebsd => {
+ "e-p:32:32:32\
+ -i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
+ -f32:32:32-f64:64:64\
+ -v64:64:64-v128:64:128\
+ -a0:0:64-n32".to_string()
+ }
+ },
+
+ target_triple: target_triple,
+
+ cc_args: Vec::new(),
+ };
+}
--- /dev/null
+// Copyright 2012-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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+use std::collections::HashSet;
+use std::os;
+use std::io::IoError;
+use syntax::abi;
+use syntax::ast;
+
+pub struct RPathConfig<'a> {
+ pub os: abi::Os,
+ pub used_crates: Vec<(ast::CrateNum, Option<Path>)>,
+ pub out_filename: Path,
+ pub get_install_prefix_lib_path: ||:'a -> Path,
+ pub realpath: |&Path|:'a -> Result<Path, IoError>
+}
+
+pub fn get_rpath_flags(config: RPathConfig) -> Vec<String> {
+
+ // No rpath on windows
+ if config.os == abi::OsWin32 {
+ return Vec::new();
+ }
+
+ let mut flags = Vec::new();
+
+ if config.os == abi::OsFreebsd {
+ flags.push_all(["-Wl,-rpath,/usr/local/lib/gcc46".to_string(),
+ "-Wl,-rpath,/usr/local/lib/gcc44".to_string(),
+ "-Wl,-z,origin".to_string()]);
+ }
+
+ debug!("preparing the RPATH!");
+
+ let libs = config.used_crates.clone();
+ let libs = libs.move_iter().filter_map(|(_, l)| {
+ l.map(|p| p.clone())
+ }).collect::<Vec<_>>();
+
+ let rpaths = get_rpaths(config, libs.as_slice());
+ flags.push_all(rpaths_to_flags(rpaths.as_slice()).as_slice());
+ flags
+}
+
+fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
+ let mut ret = Vec::new();
+ for rpath in rpaths.iter() {
+ ret.push(format!("-Wl,-rpath,{}", (*rpath).as_slice()));
+ }
+ return ret;
+}
+
+fn get_rpaths(mut config: RPathConfig,
+ libs: &[Path]) -> Vec<String> {
+ debug!("output: {}", config.out_filename.display());
+ debug!("libs:");
+ for libpath in libs.iter() {
+ debug!(" {}", libpath.display());
+ }
+
+ // Use relative paths to the libraries. Binaries can be moved
+ // as long as they maintain the relative relationship to the
+ // crates they depend on.
+ let rel_rpaths = get_rpaths_relative_to_output(&mut config, libs);
+
+ // And a final backup rpath to the global library location.
+ let fallback_rpaths = vec!(get_install_prefix_rpath(config));
+
+ fn log_rpaths(desc: &str, rpaths: &[String]) {
+ debug!("{} rpaths:", desc);
+ for rpath in rpaths.iter() {
+ debug!(" {}", *rpath);
+ }
+ }
+
+ log_rpaths("relative", rel_rpaths.as_slice());
+ log_rpaths("fallback", fallback_rpaths.as_slice());
+
+ let mut rpaths = rel_rpaths;
+ rpaths.push_all(fallback_rpaths.as_slice());
+
+ // Remove duplicates
+ let rpaths = minimize_rpaths(rpaths.as_slice());
+ return rpaths;
+}
+
+fn get_rpaths_relative_to_output(config: &mut RPathConfig,
+ libs: &[Path]) -> Vec<String> {
+ libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect()
+}
+
+fn get_rpath_relative_to_output(config: &mut RPathConfig,
+ lib: &Path) -> String {
+ use std::os;
+
+ assert!(config.os != abi::OsWin32);
+
+ // Mac doesn't appear to support $ORIGIN
+ let prefix = match config.os {
+ abi::OsAndroid | abi::OsLinux | abi::OsFreebsd
+ => "$ORIGIN",
+ abi::OsMacos => "@loader_path",
+ abi::OsWin32 | abi::OsiOS => unreachable!()
+ };
+
+ let mut lib = (config.realpath)(&os::make_absolute(lib)).unwrap();
+ lib.pop();
+ let mut output = (config.realpath)(&os::make_absolute(&config.out_filename)).unwrap();
+ output.pop();
+ let relative = lib.path_relative_from(&output);
+ let relative = relative.expect("could not create rpath relative to output");
+ // FIXME (#9639): This needs to handle non-utf8 paths
+ format!("{}/{}",
+ prefix,
+ relative.as_str().expect("non-utf8 component in path"))
+}
+
+fn get_install_prefix_rpath(config: RPathConfig) -> String {
+ let path = (config.get_install_prefix_lib_path)();
+ let path = os::make_absolute(&path);
+ // FIXME (#9639): This needs to handle non-utf8 paths
+ path.as_str().expect("non-utf8 component in rpath").to_string()
+}
+
+fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
+ let mut set = HashSet::new();
+ let mut minimized = Vec::new();
+ for rpath in rpaths.iter() {
+ if set.insert(rpath.as_slice()) {
+ minimized.push(rpath.clone());
+ }
+ }
+ minimized
+}
+
+#[cfg(unix, test)]
+mod test {
+ use super::{RPathConfig};
+ use super::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output};
+ use syntax::abi;
+
+ #[test]
+ fn test_rpaths_to_flags() {
+ let flags = rpaths_to_flags([
+ "path1".to_string(),
+ "path2".to_string()
+ ]);
+ assert_eq!(flags,
+ vec!("-Wl,-rpath,path1".to_string(),
+ "-Wl,-rpath,path2".to_string()));
+ }
+
+ #[test]
+ fn test_minimize1() {
+ let res = minimize_rpaths([
+ "rpath1".to_string(),
+ "rpath2".to_string(),
+ "rpath1".to_string()
+ ]);
+ assert!(res.as_slice() == [
+ "rpath1".to_string(),
+ "rpath2".to_string()
+ ]);
+ }
+
+ #[test]
+ fn test_minimize2() {
+ let res = minimize_rpaths([
+ "1a".to_string(),
+ "2".to_string(),
+ "2".to_string(),
+ "1a".to_string(),
+ "4a".to_string(),
+ "1a".to_string(),
+ "2".to_string(),
+ "3".to_string(),
+ "4a".to_string(),
+ "3".to_string()
+ ]);
+ assert!(res.as_slice() == [
+ "1a".to_string(),
+ "2".to_string(),
+ "4a".to_string(),
+ "3".to_string()
+ ]);
+ }
+
+ #[test]
+ #[cfg(target_os = "linux")]
+ #[cfg(target_os = "android")]
+ fn test_rpath_relative() {
+ let config = &mut RPathConfig {
+ os: abi::OsLinux,
+ used_crates: Vec::new(),
+ out_filename: Path::new("bin/rustc"),
+ get_install_prefix_lib_path: || fail!(),
+ realpath: |p| Ok(p.clone())
+ };
+ let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
+ assert_eq!(res.as_slice(), "$ORIGIN/../lib");
+ }
+
+ #[test]
+ #[cfg(target_os = "freebsd")]
+ fn test_rpath_relative() {
+ let config = &mut RPathConfig {
+ os: abi::OsFreebsd,
+ used_crates: Vec::new(),
+ out_filename: Path::new("bin/rustc"),
+ get_install_prefix_lib_path: || fail!(),
+ realpath: |p| Ok(p.clone())
+ };
+ let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
+ assert_eq!(res.as_slice(), "$ORIGIN/../lib");
+ }
+
+ #[test]
+ #[cfg(target_os = "macos")]
+ fn test_rpath_relative() {
+ let config = &mut RPathConfig {
+ os: abi::OsMacos,
+ used_crates: Vec::new(),
+ out_filename: Path::new("bin/rustc"),
+ get_install_prefix_lib_path: || fail!(),
+ realpath: |p| Ok(p.clone())
+ };
+ let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
+ assert_eq!(res.as_slice(), "@loader_path/../lib");
+ }
+}
--- /dev/null
+// Copyright 2012-2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! This module implements only the Sha256 function since that is all that is needed for internal
+//! use. This implementation is not intended for external use or for any use where security is
+//! important.
+
+#![allow(deprecated)] // to_be32
+
+use std::iter::range_step;
+use std::num::Zero;
+use std::slice::bytes::{MutableByteVector, copy_memory};
+use serialize::hex::ToHex;
+
+/// Write a u32 into a vector, which must be 4 bytes long. The value is written in big-endian
+/// format.
+fn write_u32_be(dst: &mut[u8], input: u32) {
+ use std::mem::to_be32;
+ assert!(dst.len() == 4);
+ unsafe {
+ let x = dst.unsafe_mut_ref(0) as *mut _ as *mut u32;
+ *x = to_be32(input);
+ }
+}
+
+/// Read a vector of bytes into a vector of u32s. The values are read in big-endian format.
+fn read_u32v_be(dst: &mut[u32], input: &[u8]) {
+ use std::mem::to_be32;
+ assert!(dst.len() * 4 == input.len());
+ unsafe {
+ let mut x = dst.unsafe_mut_ref(0) as *mut _ as *mut u32;
+ let mut y = input.unsafe_ref(0) as *const _ as *const u32;
+ for _ in range(0, dst.len()) {
+ *x = to_be32(*y);
+ x = x.offset(1);
+ y = y.offset(1);
+ }
+ }
+}
+
+trait ToBits {
+ /// Convert the value in bytes to the number of bits, a tuple where the 1st item is the
+ /// high-order value and the 2nd item is the low order value.
+ fn to_bits(self) -> (Self, Self);
+}
+
+impl ToBits for u64 {
+ fn to_bits(self) -> (u64, u64) {
+ return (self >> 61, self << 3);
+ }
+}
+
+/// Adds the specified number of bytes to the bit count. fail!() if this would cause numeric
+/// overflow.
+fn add_bytes_to_bits<T: Int + CheckedAdd + ToBits>(bits: T, bytes: T) -> T {
+ let (new_high_bits, new_low_bits) = bytes.to_bits();
+
+ if new_high_bits > Zero::zero() {
+ fail!("numeric overflow occurred.")
+ }
+
+ match bits.checked_add(&new_low_bits) {
+ Some(x) => return x,
+ None => fail!("numeric overflow occurred.")
+ }
+}
+
+/// A FixedBuffer, likes its name implies, is a fixed size buffer. When the buffer becomes full, it
+/// must be processed. The input() method takes care of processing and then clearing the buffer
+/// automatically. However, other methods do not and require the caller to process the buffer. Any
+/// method that modifies the buffer directory or provides the caller with bytes that can be modified
+/// results in those bytes being marked as used by the buffer.
+trait FixedBuffer {
+ /// Input a vector of bytes. If the buffer becomes full, process it with the provided
+ /// function and then clear the buffer.
+ fn input(&mut self, input: &[u8], func: |&[u8]|);
+
+ /// Reset the buffer.
+ fn reset(&mut self);
+
+ /// Zero the buffer up until the specified index. The buffer position currently must not be
+ /// greater than that index.
+ fn zero_until(&mut self, idx: uint);
+
+ /// Get a slice of the buffer of the specified size. There must be at least that many bytes
+ /// remaining in the buffer.
+ fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8];
+
+ /// Get the current buffer. The buffer must already be full. This clears the buffer as well.
+ fn full_buffer<'s>(&'s mut self) -> &'s [u8];
+
+ /// Get the current position of the buffer.
+ fn position(&self) -> uint;
+
+ /// Get the number of bytes remaining in the buffer until it is full.
+ fn remaining(&self) -> uint;
+
+ /// Get the size of the buffer
+ fn size(&self) -> uint;
+}
+
+/// A FixedBuffer of 64 bytes useful for implementing Sha256 which has a 64 byte blocksize.
+struct FixedBuffer64 {
+ buffer: [u8, ..64],
+ buffer_idx: uint,
+}
+
+impl FixedBuffer64 {
+ /// Create a new FixedBuffer64
+ fn new() -> FixedBuffer64 {
+ return FixedBuffer64 {
+ buffer: [0u8, ..64],
+ buffer_idx: 0
+ };
+ }
+}
+
+impl FixedBuffer for FixedBuffer64 {
+ fn input(&mut self, input: &[u8], func: |&[u8]|) {
+ let mut i = 0;
+
+ let size = self.size();
+
+ // If there is already data in the buffer, copy as much as we can into it and process
+ // the data if the buffer becomes full.
+ if self.buffer_idx != 0 {
+ let buffer_remaining = size - self.buffer_idx;
+ if input.len() >= buffer_remaining {
+ copy_memory(
+ self.buffer.mut_slice(self.buffer_idx, size),
+ input.slice_to(buffer_remaining));
+ self.buffer_idx = 0;
+ func(self.buffer);
+ i += buffer_remaining;
+ } else {
+ copy_memory(
+ self.buffer.mut_slice(self.buffer_idx, self.buffer_idx + input.len()),
+ input);
+ self.buffer_idx += input.len();
+ return;
+ }
+ }
+
+ // While we have at least a full buffer size chunk's worth of data, process that data
+ // without copying it into the buffer
+ while input.len() - i >= size {
+ func(input.slice(i, i + size));
+ i += size;
+ }
+
+ // Copy any input data into the buffer. At this point in the method, the amount of
+ // data left in the input vector will be less than the buffer size and the buffer will
+ // be empty.
+ let input_remaining = input.len() - i;
+ copy_memory(
+ self.buffer.mut_slice(0, input_remaining),
+ input.slice_from(i));
+ self.buffer_idx += input_remaining;
+ }
+
+ fn reset(&mut self) {
+ self.buffer_idx = 0;
+ }
+
+ fn zero_until(&mut self, idx: uint) {
+ assert!(idx >= self.buffer_idx);
+ self.buffer.mut_slice(self.buffer_idx, idx).set_memory(0);
+ self.buffer_idx = idx;
+ }
+
+ fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8] {
+ self.buffer_idx += len;
+ return self.buffer.mut_slice(self.buffer_idx - len, self.buffer_idx);
+ }
+
+ fn full_buffer<'s>(&'s mut self) -> &'s [u8] {
+ assert!(self.buffer_idx == 64);
+ self.buffer_idx = 0;
+ return self.buffer.slice_to(64);
+ }
+
+ fn position(&self) -> uint { self.buffer_idx }
+
+ fn remaining(&self) -> uint { 64 - self.buffer_idx }
+
+ fn size(&self) -> uint { 64 }
+}
+
+/// The StandardPadding trait adds a method useful for Sha256 to a FixedBuffer struct.
+trait StandardPadding {
+ /// Add padding to the buffer. The buffer must not be full when this method is called and is
+ /// guaranteed to have exactly rem remaining bytes when it returns. If there are not at least
+ /// rem bytes available, the buffer will be zero padded, processed, cleared, and then filled
+ /// with zeros again until only rem bytes are remaining.
+ fn standard_padding(&mut self, rem: uint, func: |&[u8]|);
+}
+
+impl <T: FixedBuffer> StandardPadding for T {
+ fn standard_padding(&mut self, rem: uint, func: |&[u8]|) {
+ let size = self.size();
+
+ self.next(1)[0] = 128;
+
+ if self.remaining() < rem {
+ self.zero_until(size);
+ func(self.full_buffer());
+ }
+
+ self.zero_until(size - rem);
+ }
+}
+
+/// The Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2
+/// family of digest functions.
+pub trait Digest {
+ /// Provide message data.
+ ///
+ /// # Arguments
+ ///
+ /// * input - A vector of message data
+ fn input(&mut self, input: &[u8]);
+
+ /// Retrieve the digest result. This method may be called multiple times.
+ ///
+ /// # Arguments
+ ///
+ /// * out - the vector to hold the result. Must be large enough to contain output_bits().
+ fn result(&mut self, out: &mut [u8]);
+
+ /// Reset the digest. This method must be called after result() and before supplying more
+ /// data.
+ fn reset(&mut self);
+
+ /// Get the output size in bits.
+ fn output_bits(&self) -> uint;
+
+ /// Convenience function that feeds a string into a digest.
+ ///
+ /// # Arguments
+ ///
+ /// * `input` The string to feed into the digest
+ fn input_str(&mut self, input: &str) {
+ self.input(input.as_bytes());
+ }
+
+ /// Convenience function that retrieves the result of a digest as a
+ /// newly allocated vec of bytes.
+ fn result_bytes(&mut self) -> Vec<u8> {
+ let mut buf = Vec::from_elem((self.output_bits()+7)/8, 0u8);
+ self.result(buf.as_mut_slice());
+ buf
+ }
+
+ /// Convenience function that retrieves the result of a digest as a
+ /// String in hexadecimal format.
+ fn result_str(&mut self) -> String {
+ self.result_bytes().as_slice().to_hex().to_string()
+ }
+}
+
+// A structure that represents that state of a digest computation for the SHA-2 512 family of digest
+// functions
+struct Engine256State {
+ h0: u32,
+ h1: u32,
+ h2: u32,
+ h3: u32,
+ h4: u32,
+ h5: u32,
+ h6: u32,
+ h7: u32,
+}
+
+impl Engine256State {
+ fn new(h: &[u32, ..8]) -> Engine256State {
+ return Engine256State {
+ h0: h[0],
+ h1: h[1],
+ h2: h[2],
+ h3: h[3],
+ h4: h[4],
+ h5: h[5],
+ h6: h[6],
+ h7: h[7]
+ };
+ }
+
+ fn reset(&mut self, h: &[u32, ..8]) {
+ self.h0 = h[0];
+ self.h1 = h[1];
+ self.h2 = h[2];
+ self.h3 = h[3];
+ self.h4 = h[4];
+ self.h5 = h[5];
+ self.h6 = h[6];
+ self.h7 = h[7];
+ }
+
+ fn process_block(&mut self, data: &[u8]) {
+ fn ch(x: u32, y: u32, z: u32) -> u32 {
+ ((x & y) ^ ((!x) & z))
+ }
+
+ fn maj(x: u32, y: u32, z: u32) -> u32 {
+ ((x & y) ^ (x & z) ^ (y & z))
+ }
+
+ fn sum0(x: u32) -> u32 {
+ ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10))
+ }
+
+ fn sum1(x: u32) -> u32 {
+ ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7))
+ }
+
+ fn sigma0(x: u32) -> u32 {
+ ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3)
+ }
+
+ fn sigma1(x: u32) -> u32 {
+ ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10)
+ }
+
+ let mut a = self.h0;
+ let mut b = self.h1;
+ let mut c = self.h2;
+ let mut d = self.h3;
+ let mut e = self.h4;
+ let mut f = self.h5;
+ let mut g = self.h6;
+ let mut h = self.h7;
+
+ let mut w = [0u32, ..64];
+
+ // Sha-512 and Sha-256 use basically the same calculations which are implemented
+ // by these macros. Inlining the calculations seems to result in better generated code.
+ macro_rules! schedule_round( ($t:expr) => (
+ w[$t] = sigma1(w[$t - 2]) + w[$t - 7] + sigma0(w[$t - 15]) + w[$t - 16];
+ )
+ )
+
+ macro_rules! sha2_round(
+ ($A:ident, $B:ident, $C:ident, $D:ident,
+ $E:ident, $F:ident, $G:ident, $H:ident, $K:ident, $t:expr) => (
+ {
+ $H += sum1($E) + ch($E, $F, $G) + $K[$t] + w[$t];
+ $D += $H;
+ $H += sum0($A) + maj($A, $B, $C);
+ }
+ )
+ )
+
+ read_u32v_be(w.mut_slice(0, 16), data);
+
+ // Putting the message schedule inside the same loop as the round calculations allows for
+ // the compiler to generate better code.
+ for t in range_step(0u, 48, 8) {
+ schedule_round!(t + 16);
+ schedule_round!(t + 17);
+ schedule_round!(t + 18);
+ schedule_round!(t + 19);
+ schedule_round!(t + 20);
+ schedule_round!(t + 21);
+ schedule_round!(t + 22);
+ schedule_round!(t + 23);
+
+ sha2_round!(a, b, c, d, e, f, g, h, K32, t);
+ sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
+ sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
+ sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3);
+ sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4);
+ sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
+ sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
+ sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
+ }
+
+ for t in range_step(48u, 64, 8) {
+ sha2_round!(a, b, c, d, e, f, g, h, K32, t);
+ sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
+ sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
+ sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3);
+ sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4);
+ sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
+ sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
+ sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
+ }
+
+ self.h0 += a;
+ self.h1 += b;
+ self.h2 += c;
+ self.h3 += d;
+ self.h4 += e;
+ self.h5 += f;
+ self.h6 += g;
+ self.h7 += h;
+ }
+}
+
+static K32: [u32, ..64] = [
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+];
+
+// A structure that keeps track of the state of the Sha-256 operation and contains the logic
+// necessary to perform the final calculations.
+struct Engine256 {
+ length_bits: u64,
+ buffer: FixedBuffer64,
+ state: Engine256State,
+ finished: bool,
+}
+
+impl Engine256 {
+ fn new(h: &[u32, ..8]) -> Engine256 {
+ return Engine256 {
+ length_bits: 0,
+ buffer: FixedBuffer64::new(),
+ state: Engine256State::new(h),
+ finished: false
+ }
+ }
+
+ fn reset(&mut self, h: &[u32, ..8]) {
+ self.length_bits = 0;
+ self.buffer.reset();
+ self.state.reset(h);
+ self.finished = false;
+ }
+
+ fn input(&mut self, input: &[u8]) {
+ assert!(!self.finished)
+ // Assumes that input.len() can be converted to u64 without overflow
+ self.length_bits = add_bytes_to_bits(self.length_bits, input.len() as u64);
+ let self_state = &mut self.state;
+ self.buffer.input(input, |input: &[u8]| { self_state.process_block(input) });
+ }
+
+ fn finish(&mut self) {
+ if self.finished {
+ return;
+ }
+
+ let self_state = &mut self.state;
+ self.buffer.standard_padding(8, |input: &[u8]| { self_state.process_block(input) });
+ write_u32_be(self.buffer.next(4), (self.length_bits >> 32) as u32 );
+ write_u32_be(self.buffer.next(4), self.length_bits as u32);
+ self_state.process_block(self.buffer.full_buffer());
+
+ self.finished = true;
+ }
+}
+
+/// The SHA-256 hash algorithm
+pub struct Sha256 {
+ engine: Engine256
+}
+
+impl Sha256 {
+ /// Construct a new instance of a SHA-256 digest.
+ pub fn new() -> Sha256 {
+ Sha256 {
+ engine: Engine256::new(&H256)
+ }
+ }
+}
+
+impl Digest for Sha256 {
+ fn input(&mut self, d: &[u8]) {
+ self.engine.input(d);
+ }
+
+ fn result(&mut self, out: &mut [u8]) {
+ self.engine.finish();
+
+ write_u32_be(out.mut_slice(0, 4), self.engine.state.h0);
+ write_u32_be(out.mut_slice(4, 8), self.engine.state.h1);
+ write_u32_be(out.mut_slice(8, 12), self.engine.state.h2);
+ write_u32_be(out.mut_slice(12, 16), self.engine.state.h3);
+ write_u32_be(out.mut_slice(16, 20), self.engine.state.h4);
+ write_u32_be(out.mut_slice(20, 24), self.engine.state.h5);
+ write_u32_be(out.mut_slice(24, 28), self.engine.state.h6);
+ write_u32_be(out.mut_slice(28, 32), self.engine.state.h7);
+ }
+
+ fn reset(&mut self) {
+ self.engine.reset(&H256);
+ }
+
+ fn output_bits(&self) -> uint { 256 }
+}
+
+static H256: [u32, ..8] = [
+ 0x6a09e667,
+ 0xbb67ae85,
+ 0x3c6ef372,
+ 0xa54ff53a,
+ 0x510e527f,
+ 0x9b05688c,
+ 0x1f83d9ab,
+ 0x5be0cd19
+];
+
+#[cfg(test)]
+mod tests {
+ extern crate rand;
+
+ use super::{Digest, Sha256, FixedBuffer};
+ use std::num::Bounded;
+ use self::rand::isaac::IsaacRng;
+ use self::rand::Rng;
+ use serialize::hex::FromHex;
+
+ // A normal addition - no overflow occurs
+ #[test]
+ fn test_add_bytes_to_bits_ok() {
+ assert!(super::add_bytes_to_bits::<u64>(100, 10) == 180);
+ }
+
+ // A simple failure case - adding 1 to the max value
+ #[test]
+ #[should_fail]
+ fn test_add_bytes_to_bits_overflow() {
+ super::add_bytes_to_bits::<u64>(Bounded::max_value(), 1);
+ }
+
+ struct Test {
+ input: String,
+ output_str: String,
+ }
+
+ fn test_hash<D: Digest>(sh: &mut D, tests: &[Test]) {
+ // Test that it works when accepting the message all at once
+ for t in tests.iter() {
+ sh.reset();
+ sh.input_str(t.input.as_slice());
+ let out_str = sh.result_str();
+ assert!(out_str == t.output_str);
+ }
+
+ // Test that it works when accepting the message in pieces
+ for t in tests.iter() {
+ sh.reset();
+ let len = t.input.len();
+ let mut left = len;
+ while left > 0u {
+ let take = (left + 1u) / 2u;
+ sh.input_str(t.input
+ .as_slice()
+ .slice(len - left, take + len - left));
+ left = left - take;
+ }
+ let out_str = sh.result_str();
+ assert!(out_str == t.output_str);
+ }
+ }
+
+ #[test]
+ fn test_sha256() {
+ // Examples from wikipedia
+ let wikipedia_tests = vec!(
+ Test {
+ input: "".to_string(),
+ output_str: "e3b0c44298fc1c149afb\
+ f4c8996fb92427ae41e4649b934ca495991b7852b855".to_string()
+ },
+ Test {
+ input: "The quick brown fox jumps over the lazy \
+ dog".to_string(),
+ output_str: "d7a8fbb307d7809469ca\
+ 9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592".to_string()
+ },
+ Test {
+ input: "The quick brown fox jumps over the lazy \
+ dog.".to_string(),
+ output_str: "ef537f25c895bfa78252\
+ 6529a9b63d97aa631564d5d789c2b765448c8635fb6c".to_string()
+ });
+
+ let tests = wikipedia_tests;
+
+ let mut sh = box Sha256::new();
+
+ test_hash(&mut *sh, tests.as_slice());
+ }
+
+ /// Feed 1,000,000 'a's into the digest with varying input sizes and check that the result is
+ /// correct.
+ fn test_digest_1million_random<D: Digest>(digest: &mut D, blocksize: uint, expected: &str) {
+ let total_size = 1000000;
+ let buffer = Vec::from_elem(blocksize * 2, 'a' as u8);
+ let mut rng = IsaacRng::new_unseeded();
+ let mut count = 0;
+
+ digest.reset();
+
+ while count < total_size {
+ let next: uint = rng.gen_range(0, 2 * blocksize + 1);
+ let remaining = total_size - count;
+ let size = if next > remaining { remaining } else { next };
+ digest.input(buffer.slice_to(size));
+ count += size;
+ }
+
+ let result_str = digest.result_str();
+ let result_bytes = digest.result_bytes();
+
+ assert_eq!(expected, result_str.as_slice());
+
+ let expected_vec: Vec<u8> = expected.from_hex()
+ .unwrap()
+ .move_iter()
+ .collect();
+ assert_eq!(expected_vec, result_bytes);
+ }
+
+ #[test]
+ fn test_1million_random_sha256() {
+ let mut sh = Sha256::new();
+ test_digest_1million_random(
+ &mut sh,
+ 64,
+ "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");
+ }
+}
+
+#[cfg(test)]
+mod bench {
+ extern crate test;
+ use self::test::Bencher;
+ use super::{Sha256, FixedBuffer, Digest};
+
+ #[bench]
+ pub fn sha256_10(b: &mut Bencher) {
+ let mut sh = Sha256::new();
+ let bytes = [1u8, ..10];
+ b.iter(|| {
+ sh.input(bytes);
+ });
+ b.bytes = bytes.len() as u64;
+ }
+
+ #[bench]
+ pub fn sha256_1k(b: &mut Bencher) {
+ let mut sh = Sha256::new();
+ let bytes = [1u8, ..1024];
+ b.iter(|| {
+ sh.input(bytes);
+ });
+ b.bytes = bytes.len() as u64;
+ }
+
+ #[bench]
+ pub fn sha256_64k(b: &mut Bencher) {
+ let mut sh = Sha256::new();
+ let bytes = [1u8, ..65536];
+ b.iter(|| {
+ sh.input(bytes);
+ });
+ b.bytes = bytes.len() as u64;
+ }
+}
--- /dev/null
+// Copyright 2012-2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Calculation and management of a Strict Version Hash for crates
+//!
+//! # Today's ABI problem
+//!
+//! In today's implementation of rustc, it is incredibly difficult to achieve
+//! forward binary compatibility without resorting to C-like interfaces. Within
+//! rust code itself, abi details such as symbol names suffer from a variety of
+//! unrelated factors to code changing such as the "def id drift" problem. This
+//! ends up yielding confusing error messages about metadata mismatches and
+//! such.
+//!
+//! The core of this problem is when an upstream dependency changes and
+//! downstream dependents are not recompiled. This causes compile errors because
+//! the upstream crate's metadata has changed but the downstream crates are
+//! still referencing the older crate's metadata.
+//!
+//! This problem exists for many reasons, the primary of which is that rust does
+//! not currently support forwards ABI compatibility (in place upgrades of a
+//! crate).
+//!
+//! # SVH and how it alleviates the problem
+//!
+//! With all of this knowledge on hand, this module contains the implementation
+//! of a notion of a "Strict Version Hash" for a crate. This is essentially a
+//! hash of all contents of a crate which can somehow be exposed to downstream
+//! crates.
+//!
+//! This hash is currently calculated by just hashing the AST, but this is
+//! obviously wrong (doc changes should not result in an incompatible ABI).
+//! Implementation-wise, this is required at this moment in time.
+//!
+//! By encoding this strict version hash into all crate's metadata, stale crates
+//! can be detected immediately and error'd about by rustc itself.
+//!
+//! # Relevant links
+//!
+//! Original issue: https://github.com/rust-lang/rust/issues/10207
+
+use std::fmt;
+use std::hash::Hash;
+use std::hash::sip::SipState;
+use std::iter::range_step;
+use syntax::ast;
+use syntax::visit;
+
+#[deriving(Clone, PartialEq)]
+pub struct Svh {
+ hash: String,
+}
+
+impl Svh {
+ pub fn new(hash: &str) -> Svh {
+ assert!(hash.len() == 16);
+ Svh { hash: hash.to_string() }
+ }
+
+ pub fn as_str<'a>(&'a self) -> &'a str {
+ self.hash.as_slice()
+ }
+
+ pub fn calculate(metadata: &Vec<String>, krate: &ast::Crate) -> Svh {
+ // FIXME (#14132): This is better than it used to be, but it still not
+ // ideal. We now attempt to hash only the relevant portions of the
+ // Crate AST as well as the top-level crate attributes. (However,
+ // the hashing of the crate attributes should be double-checked
+ // to ensure it is not incorporating implementation artifacts into
+ // the hash that are not otherwise visible.)
+
+ // FIXME: this should use SHA1, not SipHash. SipHash is not built to
+ // avoid collisions.
+ let mut state = SipState::new();
+
+ for data in metadata.iter() {
+ data.hash(&mut state);
+ }
+
+ {
+ let mut visit = svh_visitor::make(&mut state);
+ visit::walk_crate(&mut visit, krate, ());
+ }
+
+ // FIXME (#14132): This hash is still sensitive to e.g. the
+ // spans of the crate Attributes and their underlying
+ // MetaItems; we should make ContentHashable impl for those
+ // types and then use hash_content. But, since all crate
+ // attributes should appear near beginning of the file, it is
+ // not such a big deal to be sensitive to their spans for now.
+ //
+ // We hash only the MetaItems instead of the entire Attribute
+ // to avoid hashing the AttrId
+ for attr in krate.attrs.iter() {
+ attr.node.value.hash(&mut state);
+ }
+
+ let hash = state.result();
+ return Svh {
+ hash: range_step(0u, 64u, 4u).map(|i| hex(hash >> i)).collect()
+ };
+
+ fn hex(b: u64) -> char {
+ let b = (b & 0xf) as u8;
+ let b = match b {
+ 0 .. 9 => '0' as u8 + b,
+ _ => 'a' as u8 + b - 10,
+ };
+ b as char
+ }
+ }
+}
+
+impl fmt::Show for Svh {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.pad(self.as_str())
+ }
+}
+
+// FIXME (#14132): Even this SVH computation still has implementation
+// artifacts: namely, the order of item declaration will affect the
+// hash computation, but for many kinds of items the order of
+// declaration should be irrelevant to the ABI.
+
+mod svh_visitor {
+ use syntax::ast;
+ use syntax::ast::*;
+ use syntax::codemap::Span;
+ use syntax::parse::token;
+ use syntax::print::pprust;
+ use syntax::visit;
+ use syntax::visit::{Visitor, FnKind};
+
+ use std::hash::Hash;
+ use std::hash::sip::SipState;
+
+ pub struct StrictVersionHashVisitor<'a> {
+ pub st: &'a mut SipState,
+ }
+
+ pub fn make<'a>(st: &'a mut SipState) -> StrictVersionHashVisitor<'a> {
+ StrictVersionHashVisitor { st: st }
+ }
+
+ // To off-load the bulk of the hash-computation on deriving(Hash),
+ // we define a set of enums corresponding to the content that our
+ // crate visitor will encounter as it traverses the ast.
+ //
+ // The important invariant is that all of the Saw*Component enums
+ // do not carry any Spans, Names, or Idents.
+ //
+ // Not carrying any Names/Idents is the important fix for problem
+ // noted on PR #13948: using the ident.name as the basis for a
+ // hash leads to unstable SVH, because ident.name is just an index
+ // into intern table (i.e. essentially a random address), not
+ // computed from the name content.
+ //
+ // With the below enums, the SVH computation is not sensitive to
+ // artifacts of how rustc was invoked nor of how the source code
+ // was laid out. (Or at least it is *less* sensitive.)
+
+ // This enum represents the different potential bits of code the
+ // visitor could encounter that could affect the ABI for the crate,
+ // and assigns each a distinct tag to feed into the hash computation.
+ #[deriving(Hash)]
+ enum SawAbiComponent<'a> {
+
+ // FIXME (#14132): should we include (some function of)
+ // ident.ctxt as well?
+ SawIdent(token::InternedString),
+ SawStructDef(token::InternedString),
+
+ SawLifetimeRef(token::InternedString),
+ SawLifetimeDecl(token::InternedString),
+
+ SawMod,
+ SawViewItem,
+ SawForeignItem,
+ SawItem,
+ SawDecl,
+ SawTy,
+ SawGenerics,
+ SawFn,
+ SawTyMethod,
+ SawTraitMethod,
+ SawStructField,
+ SawVariant,
+ SawExplicitSelf,
+ SawPath,
+ SawOptLifetimeRef,
+ SawBlock,
+ SawPat,
+ SawLocal,
+ SawArm,
+ SawExpr(SawExprComponent<'a>),
+ SawStmt(SawStmtComponent),
+ }
+
+ /// SawExprComponent carries all of the information that we want
+ /// to include in the hash that *won't* be covered by the
+ /// subsequent recursive traversal of the expression's
+ /// substructure by the visitor.
+ ///
+ /// We know every Expr_ variant is covered by a variant because
+ /// `fn saw_expr` maps each to some case below. Ensuring that
+ /// each variant carries an appropriate payload has to be verified
+ /// by hand.
+ ///
+ /// (However, getting that *exactly* right is not so important
+ /// because the SVH is just a developer convenience; there is no
+ /// guarantee of collision-freedom, hash collisions are just
+ /// (hopefully) unlikely.)
+ #[deriving(Hash)]
+ pub enum SawExprComponent<'a> {
+
+ SawExprLoop(Option<token::InternedString>),
+ SawExprField(token::InternedString),
+ SawExprBreak(Option<token::InternedString>),
+ SawExprAgain(Option<token::InternedString>),
+
+ SawExprVstore,
+ SawExprBox,
+ SawExprVec,
+ SawExprCall,
+ SawExprMethodCall,
+ SawExprTup,
+ SawExprBinary(ast::BinOp),
+ SawExprUnary(ast::UnOp),
+ SawExprLit(ast::Lit_),
+ SawExprCast,
+ SawExprIf,
+ SawExprWhile,
+ SawExprMatch,
+ SawExprFnBlock,
+ SawExprProc,
+ SawExprBlock,
+ SawExprAssign,
+ SawExprAssignOp(ast::BinOp),
+ SawExprIndex,
+ SawExprPath,
+ SawExprAddrOf(ast::Mutability),
+ SawExprRet,
+ SawExprInlineAsm(&'a ast::InlineAsm),
+ SawExprStruct,
+ SawExprRepeat,
+ SawExprParen,
+ }
+
+ fn saw_expr<'a>(node: &'a Expr_) -> SawExprComponent<'a> {
+ match *node {
+ ExprVstore(..) => SawExprVstore,
+ ExprBox(..) => SawExprBox,
+ ExprVec(..) => SawExprVec,
+ ExprCall(..) => SawExprCall,
+ ExprMethodCall(..) => SawExprMethodCall,
+ ExprTup(..) => SawExprTup,
+ ExprBinary(op, _, _) => SawExprBinary(op),
+ ExprUnary(op, _) => SawExprUnary(op),
+ ExprLit(lit) => SawExprLit(lit.node.clone()),
+ ExprCast(..) => SawExprCast,
+ ExprIf(..) => SawExprIf,
+ ExprWhile(..) => SawExprWhile,
+ ExprLoop(_, id) => SawExprLoop(id.map(content)),
+ ExprMatch(..) => SawExprMatch,
+ ExprFnBlock(..) => SawExprFnBlock,
+ ExprProc(..) => SawExprProc,
+ ExprBlock(..) => SawExprBlock,
+ ExprAssign(..) => SawExprAssign,
+ ExprAssignOp(op, _, _) => SawExprAssignOp(op),
+ ExprField(_, id, _) => SawExprField(content(id.node)),
+ ExprIndex(..) => SawExprIndex,
+ ExprPath(..) => SawExprPath,
+ ExprAddrOf(m, _) => SawExprAddrOf(m),
+ ExprBreak(id) => SawExprBreak(id.map(content)),
+ ExprAgain(id) => SawExprAgain(id.map(content)),
+ ExprRet(..) => SawExprRet,
+ ExprInlineAsm(ref asm) => SawExprInlineAsm(asm),
+ ExprStruct(..) => SawExprStruct,
+ ExprRepeat(..) => SawExprRepeat,
+ ExprParen(..) => SawExprParen,
+
+ // just syntactic artifacts, expanded away by time of SVH.
+ ExprForLoop(..) => unreachable!(),
+ ExprMac(..) => unreachable!(),
+ }
+ }
+
+ /// SawStmtComponent is analogous to SawExprComponent, but for statements.
+ #[deriving(Hash)]
+ pub enum SawStmtComponent {
+ SawStmtDecl,
+ SawStmtExpr,
+ SawStmtSemi,
+ }
+
+ fn saw_stmt(node: &Stmt_) -> SawStmtComponent {
+ match *node {
+ StmtDecl(..) => SawStmtDecl,
+ StmtExpr(..) => SawStmtExpr,
+ StmtSemi(..) => SawStmtSemi,
+ StmtMac(..) => unreachable!(),
+ }
+ }
+
+ // Ad-hoc overloading between Ident and Name to their intern table lookups.
+ trait InternKey { fn get_content(self) -> token::InternedString; }
+ impl InternKey for Ident {
+ fn get_content(self) -> token::InternedString { token::get_ident(self) }
+ }
+ impl InternKey for Name {
+ fn get_content(self) -> token::InternedString { token::get_name(self) }
+ }
+ fn content<K:InternKey>(k: K) -> token::InternedString { k.get_content() }
+
+ // local short-hand eases writing signatures of syntax::visit mod.
+ type E = ();
+
+ impl<'a> Visitor<E> for StrictVersionHashVisitor<'a> {
+
+ fn visit_mac(&mut self, macro: &Mac, e: E) {
+ // macro invocations, namely macro_rules definitions,
+ // *can* appear as items, even in the expanded crate AST.
+
+ if macro_name(macro).get() == "macro_rules" {
+ // Pretty-printing definition to a string strips out
+ // surface artifacts (currently), such as the span
+ // information, yielding a content-based hash.
+
+ // FIXME (#14132): building temporary string is
+ // expensive; a direct content-based hash on token
+ // trees might be faster. Implementing this is far
+ // easier in short term.
+ let macro_defn_as_string =
+ pprust::to_string(|pp_state| pp_state.print_mac(macro));
+ macro_defn_as_string.hash(self.st);
+ } else {
+ // It is not possible to observe any kind of macro
+ // invocation at this stage except `macro_rules!`.
+ fail!("reached macro somehow: {}",
+ pprust::to_string(|pp_state| pp_state.print_mac(macro)));
+ }
+
+ visit::walk_mac(self, macro, e);
+
+ fn macro_name(macro: &Mac) -> token::InternedString {
+ match ¯o.node {
+ &MacInvocTT(ref path, ref _tts, ref _stx_ctxt) => {
+ let s = path.segments.as_slice();
+ assert_eq!(s.len(), 1);
+ content(s[0].identifier)
+ }
+ }
+ }
+ }
+
+ fn visit_struct_def(&mut self, s: &StructDef, ident: Ident,
+ g: &Generics, _: NodeId, e: E) {
+ SawStructDef(content(ident)).hash(self.st);
+ visit::walk_generics(self, g, e.clone());
+ visit::walk_struct_def(self, s, e)
+ }
+
+ fn visit_variant(&mut self, v: &Variant, g: &Generics, e: E) {
+ SawVariant.hash(self.st);
+ // walk_variant does not call walk_generics, so do it here.
+ visit::walk_generics(self, g, e.clone());
+ visit::walk_variant(self, v, g, e)
+ }
+
+ fn visit_opt_lifetime_ref(&mut self, _: Span, l: &Option<Lifetime>, env: E) {
+ SawOptLifetimeRef.hash(self.st);
+ // (This is a strange method in the visitor trait, in that
+ // it does not expose a walk function to do the subroutine
+ // calls.)
+ match *l {
+ Some(ref l) => self.visit_lifetime_ref(l, env),
+ None => ()
+ }
+ }
+
+ // All of the remaining methods just record (in the hash
+ // SipState) that the visitor saw that particular variant
+ // (with its payload), and continue walking as the default
+ // visitor would.
+ //
+ // Some of the implementations have some notes as to how one
+ // might try to make their SVH computation less discerning
+ // (e.g. by incorporating reachability analysis). But
+ // currently all of their implementations are uniform and
+ // uninteresting.
+ //
+ // (If you edit a method such that it deviates from the
+ // pattern, please move that method up above this comment.)
+
+ fn visit_ident(&mut self, _: Span, ident: Ident, _: E) {
+ SawIdent(content(ident)).hash(self.st);
+ }
+
+ fn visit_lifetime_ref(&mut self, l: &Lifetime, _: E) {
+ SawLifetimeRef(content(l.name)).hash(self.st);
+ }
+
+ fn visit_lifetime_decl(&mut self, l: &Lifetime, _: E) {
+ SawLifetimeDecl(content(l.name)).hash(self.st);
+ }
+
+ // We do recursively walk the bodies of functions/methods
+ // (rather than omitting their bodies from the hash) since
+ // monomorphization and cross-crate inlining generally implies
+ // that a change to a crate body will require downstream
+ // crates to be recompiled.
+ fn visit_expr(&mut self, ex: &Expr, e: E) {
+ SawExpr(saw_expr(&ex.node)).hash(self.st); visit::walk_expr(self, ex, e)
+ }
+
+ fn visit_stmt(&mut self, s: &Stmt, e: E) {
+ SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s, e)
+ }
+
+ fn visit_view_item(&mut self, i: &ViewItem, e: E) {
+ // Two kinds of view items can affect the ABI for a crate:
+ // exported `pub use` view items (since that may expose
+ // items that downstream crates can call), and `use
+ // foo::Trait`, since changing that may affect method
+ // resolution.
+ //
+ // The simplest approach to handling both of the above is
+ // just to adopt the same simple-minded (fine-grained)
+ // hash that I am deploying elsewhere here.
+ SawViewItem.hash(self.st); visit::walk_view_item(self, i, e)
+ }
+
+ fn visit_foreign_item(&mut self, i: &ForeignItem, e: E) {
+ // FIXME (#14132) ideally we would incorporate privacy (or
+ // perhaps reachability) somewhere here, so foreign items
+ // that do not leak into downstream crates would not be
+ // part of the ABI.
+ SawForeignItem.hash(self.st); visit::walk_foreign_item(self, i, e)
+ }
+
+ fn visit_item(&mut self, i: &Item, e: E) {
+ // FIXME (#14132) ideally would incorporate reachability
+ // analysis somewhere here, so items that never leak into
+ // downstream crates (e.g. via monomorphisation or
+ // inlining) would not be part of the ABI.
+ SawItem.hash(self.st); visit::walk_item(self, i, e)
+ }
+
+ fn visit_mod(&mut self, m: &Mod, _s: Span, _n: NodeId, e: E) {
+ SawMod.hash(self.st); visit::walk_mod(self, m, e)
+ }
+
+ fn visit_decl(&mut self, d: &Decl, e: E) {
+ SawDecl.hash(self.st); visit::walk_decl(self, d, e)
+ }
+
+ fn visit_ty(&mut self, t: &Ty, e: E) {
+ SawTy.hash(self.st); visit::walk_ty(self, t, e)
+ }
+
+ fn visit_generics(&mut self, g: &Generics, e: E) {
+ SawGenerics.hash(self.st); visit::walk_generics(self, g, e)
+ }
+
+ fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId, e: E) {
+ SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s, e)
+ }
+
+ fn visit_ty_method(&mut self, t: &TypeMethod, e: E) {
+ SawTyMethod.hash(self.st); visit::walk_ty_method(self, t, e)
+ }
+
+ fn visit_trait_method(&mut self, t: &TraitMethod, e: E) {
+ SawTraitMethod.hash(self.st); visit::walk_trait_method(self, t, e)
+ }
+
+ fn visit_struct_field(&mut self, s: &StructField, e: E) {
+ SawStructField.hash(self.st); visit::walk_struct_field(self, s, e)
+ }
+
+ fn visit_explicit_self(&mut self, es: &ExplicitSelf, e: E) {
+ SawExplicitSelf.hash(self.st); visit::walk_explicit_self(self, es, e)
+ }
+
+ fn visit_path(&mut self, path: &Path, _: ast::NodeId, e: E) {
+ SawPath.hash(self.st); visit::walk_path(self, path, e)
+ }
+
+ fn visit_block(&mut self, b: &Block, e: E) {
+ SawBlock.hash(self.st); visit::walk_block(self, b, e)
+ }
+
+ fn visit_pat(&mut self, p: &Pat, e: E) {
+ SawPat.hash(self.st); visit::walk_pat(self, p, e)
+ }
+
+ fn visit_local(&mut self, l: &Local, e: E) {
+ SawLocal.hash(self.st); visit::walk_local(self, l, e)
+ }
+
+ fn visit_arm(&mut self, a: &Arm, e: E) {
+ SawArm.hash(self.st); visit::walk_arm(self, a, e)
+ }
+ }
+}
--- /dev/null
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(non_camel_case_types)]
+
+pub struct t {
+ pub module_asm: String,
+ pub data_layout: String,
+ pub target_triple: String,
+ pub cc_args: Vec<String> ,
+}
--- /dev/null
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+use target_strs;
+use syntax::abi;
+
+pub fn get_target_strs(target_triple: String, target_os: abi::Os)
+ -> target_strs::t {
+ return target_strs::t {
+ module_asm: "".to_string(),
+
+ data_layout: match target_os {
+ abi::OsMacos => {
+ "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16\
+ -i32:32:32-i64:32:64\
+ -f32:32:32-f64:32:64-v64:64:64\
+ -v128:128:128-a0:0:64-f80:128:128\
+ -n8:16:32".to_string()
+ }
+
+ abi::OsiOS => {
+ "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16\
+ -i32:32:32-i64:32:64\
+ -f32:32:32-f64:32:64-v64:64:64\
+ -v128:128:128-a0:0:64-f80:128:128\
+ -n8:16:32".to_string()
+ }
+
+ abi::OsWin32 => {
+ "e-p:32:32-f64:64:64-i64:64:64-f80:32:32-n8:16:32".to_string()
+ }
+
+ abi::OsLinux => {
+ "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string()
+ }
+ abi::OsAndroid => {
+ "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string()
+ }
+
+ abi::OsFreebsd => {
+ "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string()
+ }
+ },
+
+ target_triple: target_triple,
+
+ cc_args: vec!("-m32".to_string()),
+ };
+}
--- /dev/null
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+use target_strs;
+use syntax::abi;
+
+pub fn get_target_strs(target_triple: String, target_os: abi::Os) -> target_strs::t {
+ return target_strs::t {
+ module_asm: "".to_string(),
+
+ data_layout: match target_os {
+ abi::OsMacos => {
+ "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
+ f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
+ s0:64:64-f80:128:128-n8:16:32:64".to_string()
+ }
+
+ abi::OsiOS => {
+ "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
+ f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
+ s0:64:64-f80:128:128-n8:16:32:64".to_string()
+ }
+
+ abi::OsWin32 => {
+ // FIXME: Test this. Copied from linux (#2398)
+ "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
+ f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
+ s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
+ }
+
+ abi::OsLinux => {
+ "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
+ f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
+ s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
+ }
+ abi::OsAndroid => {
+ "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
+ f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
+ s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
+ }
+
+ abi::OsFreebsd => {
+ "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
+ f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
+ s0:64:64-f80:128:128-n8:16:32:64-S128".to_string()
+ }
+ },
+
+ target_triple: target_triple,
+
+ cc_args: vec!("-m64".to_string()),
+ };
+}
--- /dev/null
+// Copyright 2013-2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A wrapper around LLVM's archive (.a) code
+
+use libc;
+use ArchiveRef;
+
+use std::raw;
+use std::mem;
+
+pub struct ArchiveRO {
+ ptr: ArchiveRef,
+}
+
+impl ArchiveRO {
+ /// Opens a static archive for read-only purposes. This is more optimized
+ /// than the `open` method because it uses LLVM's internal `Archive` class
+ /// rather than shelling out to `ar` for everything.
+ ///
+ /// If this archive is used with a mutable method, then an error will be
+ /// raised.
+ pub fn open(dst: &Path) -> Option<ArchiveRO> {
+ unsafe {
+ let ar = dst.with_c_str(|dst| {
+ ::LLVMRustOpenArchive(dst)
+ });
+ if ar.is_null() {
+ None
+ } else {
+ Some(ArchiveRO { ptr: ar })
+ }
+ }
+ }
+
+ /// Reads a file in the archive
+ pub fn read<'a>(&'a self, file: &str) -> Option<&'a [u8]> {
+ unsafe {
+ let mut size = 0 as libc::size_t;
+ let ptr = file.with_c_str(|file| {
+ ::LLVMRustArchiveReadSection(self.ptr, file, &mut size)
+ });
+ if ptr.is_null() {
+ None
+ } else {
+ Some(mem::transmute(raw::Slice {
+ data: ptr,
+ len: size as uint,
+ }))
+ }
+ }
+ }
+}
+
+impl Drop for ArchiveRO {
+ fn drop(&mut self) {
+ unsafe {
+ ::LLVMRustDestroyArchive(self.ptr);
+ }
+ }
+}
--- /dev/null
+// Copyright 2012-2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(non_uppercase_pattern_statics)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case_functions)]
+#![allow(dead_code)]
+
+#![crate_id = "rustc_llvm#0.11.0"]
+#![crate_name = "rustc_llvm"]
+#![experimental]
+#![license = "MIT/ASL2"]
+#![crate_type = "dylib"]
+#![crate_type = "rlib"]
+#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+ html_favicon_url = "http://www.rust-lang.org/favicon.ico",
+ html_root_url = "http://doc.rust-lang.org/")]
+
+#![feature(globs)]
+#![feature(link_args)]
+#![allow(unused_attribute)] // NOTE: remove after stage0
+
+extern crate libc;
+
+use std::c_str::ToCStr;
+use libc::{c_uint, c_ushort, uint64_t, c_int, size_t, c_char};
+use libc::{c_longlong, c_ulonglong};
+use debuginfo::{DIBuilderRef, DIDescriptor,
+ DIFile, DILexicalBlock, DISubprogram, DIType,
+ DIBasicType, DIDerivedType, DICompositeType,
+ DIVariable, DIGlobalVariable, DIArray, DISubrange};
+
+pub mod archive_ro;
+
+pub type Opcode = u32;
+pub type Bool = c_uint;
+
+pub static True: Bool = 1 as Bool;
+pub static False: Bool = 0 as Bool;
+
+// Consts for the LLVM CallConv type, pre-cast to uint.
+
+#[deriving(PartialEq)]
+pub enum CallConv {
+ CCallConv = 0,
+ FastCallConv = 8,
+ ColdCallConv = 9,
+ X86StdcallCallConv = 64,
+ X86FastcallCallConv = 65,
+ X86_64_Win64 = 79,
+}
+
+pub enum Visibility {
+ LLVMDefaultVisibility = 0,
+ HiddenVisibility = 1,
+ ProtectedVisibility = 2,
+}
+
+// This enum omits the obsolete (and no-op) linkage types DLLImportLinkage,
+// DLLExportLinkage, GhostLinkage and LinkOnceODRAutoHideLinkage.
+// LinkerPrivateLinkage and LinkerPrivateWeakLinkage are not included either;
+// they've been removed in upstream LLVM commit r203866.
+pub enum Linkage {
+ ExternalLinkage = 0,
+ AvailableExternallyLinkage = 1,
+ LinkOnceAnyLinkage = 2,
+ LinkOnceODRLinkage = 3,
+ WeakAnyLinkage = 5,
+ WeakODRLinkage = 6,
+ AppendingLinkage = 7,
+ InternalLinkage = 8,
+ PrivateLinkage = 9,
+ ExternalWeakLinkage = 12,
+ CommonLinkage = 14,
+}
+
+#[deriving(Clone)]
+pub enum Attribute {
+ ZExtAttribute = 1 << 0,
+ SExtAttribute = 1 << 1,
+ NoReturnAttribute = 1 << 2,
+ InRegAttribute = 1 << 3,
+ StructRetAttribute = 1 << 4,
+ NoUnwindAttribute = 1 << 5,
+ NoAliasAttribute = 1 << 6,
+ ByValAttribute = 1 << 7,
+ NestAttribute = 1 << 8,
+ ReadNoneAttribute = 1 << 9,
+ ReadOnlyAttribute = 1 << 10,
+ NoInlineAttribute = 1 << 11,
+ AlwaysInlineAttribute = 1 << 12,
+ OptimizeForSizeAttribute = 1 << 13,
+ StackProtectAttribute = 1 << 14,
+ StackProtectReqAttribute = 1 << 15,
+ AlignmentAttribute = 31 << 16,
+ NoCaptureAttribute = 1 << 21,
+ NoRedZoneAttribute = 1 << 22,
+ NoImplicitFloatAttribute = 1 << 23,
+ NakedAttribute = 1 << 24,
+ InlineHintAttribute = 1 << 25,
+ StackAttribute = 7 << 26,
+ ReturnsTwiceAttribute = 1 << 29,
+ UWTableAttribute = 1 << 30,
+ NonLazyBindAttribute = 1 << 31,
+}
+
+#[repr(u64)]
+pub enum OtherAttribute {
+ // The following are not really exposed in
+ // the LLVM c api so instead to add these
+ // we call a wrapper function in RustWrapper
+ // that uses the C++ api.
+ SanitizeAddressAttribute = 1 << 32,
+ MinSizeAttribute = 1 << 33,
+ NoDuplicateAttribute = 1 << 34,
+ StackProtectStrongAttribute = 1 << 35,
+ SanitizeThreadAttribute = 1 << 36,
+ SanitizeMemoryAttribute = 1 << 37,
+ NoBuiltinAttribute = 1 << 38,
+ ReturnedAttribute = 1 << 39,
+ ColdAttribute = 1 << 40,
+ BuiltinAttribute = 1 << 41,
+ OptimizeNoneAttribute = 1 << 42,
+ InAllocaAttribute = 1 << 43,
+ NonNullAttribute = 1 << 44,
+}
+
+#[repr(C)]
+pub enum AttributeSet {
+ ReturnIndex = 0,
+ FunctionIndex = !0
+}
+
+// enum for the LLVM IntPredicate type
+pub enum IntPredicate {
+ IntEQ = 32,
+ IntNE = 33,
+ IntUGT = 34,
+ IntUGE = 35,
+ IntULT = 36,
+ IntULE = 37,
+ IntSGT = 38,
+ IntSGE = 39,
+ IntSLT = 40,
+ IntSLE = 41,
+}
+
+// enum for the LLVM RealPredicate type
+pub enum RealPredicate {
+ RealPredicateFalse = 0,
+ RealOEQ = 1,
+ RealOGT = 2,
+ RealOGE = 3,
+ RealOLT = 4,
+ RealOLE = 5,
+ RealONE = 6,
+ RealORD = 7,
+ RealUNO = 8,
+ RealUEQ = 9,
+ RealUGT = 10,
+ RealUGE = 11,
+ RealULT = 12,
+ RealULE = 13,
+ RealUNE = 14,
+ RealPredicateTrue = 15,
+}
+
+// The LLVM TypeKind type - must stay in sync with the def of
+// LLVMTypeKind in llvm/include/llvm-c/Core.h
+#[deriving(PartialEq)]
+#[repr(C)]
+pub enum TypeKind {
+ Void = 0,
+ Half = 1,
+ Float = 2,
+ Double = 3,
+ X86_FP80 = 4,
+ FP128 = 5,
+ PPC_FP128 = 6,
+ Label = 7,
+ Integer = 8,
+ Function = 9,
+ Struct = 10,
+ Array = 11,
+ Pointer = 12,
+ Vector = 13,
+ Metadata = 14,
+ X86_MMX = 15,
+}
+
+#[repr(C)]
+pub enum AtomicBinOp {
+ Xchg = 0,
+ Add = 1,
+ Sub = 2,
+ And = 3,
+ Nand = 4,
+ Or = 5,
+ Xor = 6,
+ Max = 7,
+ Min = 8,
+ UMax = 9,
+ UMin = 10,
+}
+
+#[repr(C)]
+pub enum AtomicOrdering {
+ NotAtomic = 0,
+ Unordered = 1,
+ Monotonic = 2,
+ // Consume = 3, // Not specified yet.
+ Acquire = 4,
+ Release = 5,
+ AcquireRelease = 6,
+ SequentiallyConsistent = 7
+}
+
+// Consts for the LLVMCodeGenFileType type (in include/llvm/c/TargetMachine.h)
+#[repr(C)]
+pub enum FileType {
+ AssemblyFile = 0,
+ ObjectFile = 1
+}
+
+pub enum Metadata {
+ MD_dbg = 0,
+ MD_tbaa = 1,
+ MD_prof = 2,
+ MD_fpmath = 3,
+ MD_range = 4,
+ MD_tbaa_struct = 5
+}
+
+// Inline Asm Dialect
+pub enum AsmDialect {
+ AD_ATT = 0,
+ AD_Intel = 1
+}
+
+#[deriving(PartialEq)]
+#[repr(C)]
+pub enum CodeGenOptLevel {
+ CodeGenLevelNone = 0,
+ CodeGenLevelLess = 1,
+ CodeGenLevelDefault = 2,
+ CodeGenLevelAggressive = 3,
+}
+
+#[repr(C)]
+pub enum RelocMode {
+ RelocDefault = 0,
+ RelocStatic = 1,
+ RelocPIC = 2,
+ RelocDynamicNoPic = 3,
+}
+
+#[repr(C)]
+pub enum CodeGenModel {
+ CodeModelDefault = 0,
+ CodeModelJITDefault = 1,
+ CodeModelSmall = 2,
+ CodeModelKernel = 3,
+ CodeModelMedium = 4,
+ CodeModelLarge = 5,
+}
+
+// Opaque pointer types
+pub enum Module_opaque {}
+pub type ModuleRef = *mut Module_opaque;
+pub enum Context_opaque {}
+pub type ContextRef = *mut Context_opaque;
+pub enum Type_opaque {}
+pub type TypeRef = *mut Type_opaque;
+pub enum Value_opaque {}
+pub type ValueRef = *mut Value_opaque;
+pub enum BasicBlock_opaque {}
+pub type BasicBlockRef = *mut BasicBlock_opaque;
+pub enum Builder_opaque {}
+pub type BuilderRef = *mut Builder_opaque;
+pub enum ExecutionEngine_opaque {}
+pub type ExecutionEngineRef = *mut ExecutionEngine_opaque;
+pub enum MemoryBuffer_opaque {}
+pub type MemoryBufferRef = *mut MemoryBuffer_opaque;
+pub enum PassManager_opaque {}
+pub type PassManagerRef = *mut PassManager_opaque;
+pub enum PassManagerBuilder_opaque {}
+pub type PassManagerBuilderRef = *mut PassManagerBuilder_opaque;
+pub enum Use_opaque {}
+pub type UseRef = *mut Use_opaque;
+pub enum TargetData_opaque {}
+pub type TargetDataRef = *mut TargetData_opaque;
+pub enum ObjectFile_opaque {}
+pub type ObjectFileRef = *mut ObjectFile_opaque;
+pub enum SectionIterator_opaque {}
+pub type SectionIteratorRef = *mut SectionIterator_opaque;
+pub enum Pass_opaque {}
+pub type PassRef = *mut Pass_opaque;
+pub enum TargetMachine_opaque {}
+pub type TargetMachineRef = *mut TargetMachine_opaque;
+pub enum Archive_opaque {}
+pub type ArchiveRef = *mut Archive_opaque;
+
+pub mod debuginfo {
+ use super::{ValueRef};
+
+ pub enum DIBuilder_opaque {}
+ pub type DIBuilderRef = *mut DIBuilder_opaque;
+
+ pub type DIDescriptor = ValueRef;
+ pub type DIScope = DIDescriptor;
+ pub type DILocation = DIDescriptor;
+ pub type DIFile = DIScope;
+ pub type DILexicalBlock = DIScope;
+ pub type DISubprogram = DIScope;
+ pub type DIType = DIDescriptor;
+ pub type DIBasicType = DIType;
+ pub type DIDerivedType = DIType;
+ pub type DICompositeType = DIDerivedType;
+ pub type DIVariable = DIDescriptor;
+ pub type DIGlobalVariable = DIDescriptor;
+ pub type DIArray = DIDescriptor;
+ pub type DISubrange = DIDescriptor;
+
+ pub enum DIDescriptorFlags {
+ FlagPrivate = 1 << 0,
+ FlagProtected = 1 << 1,
+ FlagFwdDecl = 1 << 2,
+ FlagAppleBlock = 1 << 3,
+ FlagBlockByrefStruct = 1 << 4,
+ FlagVirtual = 1 << 5,
+ FlagArtificial = 1 << 6,
+ FlagExplicit = 1 << 7,
+ FlagPrototyped = 1 << 8,
+ FlagObjcClassComplete = 1 << 9,
+ FlagObjectPointer = 1 << 10,
+ FlagVector = 1 << 11,
+ FlagStaticMember = 1 << 12
+ }
+}
+
+
+// Link to our native llvm bindings (things that we need to use the C++ api
+// for) and because llvm is written in C++ we need to link against libstdc++
+//
+// You'll probably notice that there is an omission of all LLVM libraries
+// from this location. This is because the set of LLVM libraries that we
+// link to is mostly defined by LLVM, and the `llvm-config` tool is used to
+// figure out the exact set of libraries. To do this, the build system
+// generates an llvmdeps.rs file next to this one which will be
+// automatically updated whenever LLVM is updated to include an up-to-date
+// set of the libraries we need to link to LLVM for.
+#[link(name = "rustllvm", kind = "static")]
+extern {
+ /* Create and destroy contexts. */
+ pub fn LLVMContextCreate() -> ContextRef;
+ pub fn LLVMContextDispose(C: ContextRef);
+ pub fn LLVMGetMDKindIDInContext(C: ContextRef,
+ Name: *const c_char,
+ SLen: c_uint)
+ -> c_uint;
+
+ /* Create and destroy modules. */
+ pub fn LLVMModuleCreateWithNameInContext(ModuleID: *const c_char,
+ C: ContextRef)
+ -> ModuleRef;
+ pub fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef;
+ pub fn LLVMDisposeModule(M: ModuleRef);
+
+ /** Data layout. See Module::getDataLayout. */
+ pub fn LLVMGetDataLayout(M: ModuleRef) -> *const c_char;
+ pub fn LLVMSetDataLayout(M: ModuleRef, Triple: *const c_char);
+
+ /** Target triple. See Module::getTargetTriple. */
+ pub fn LLVMGetTarget(M: ModuleRef) -> *const c_char;
+ pub fn LLVMSetTarget(M: ModuleRef, Triple: *const c_char);
+
+ /** See Module::dump. */
+ pub fn LLVMDumpModule(M: ModuleRef);
+
+ /** See Module::setModuleInlineAsm. */
+ pub fn LLVMSetModuleInlineAsm(M: ModuleRef, Asm: *const c_char);
+
+ /** See llvm::LLVMTypeKind::getTypeID. */
+ pub fn LLVMGetTypeKind(Ty: TypeRef) -> TypeKind;
+
+ /** See llvm::LLVMType::getContext. */
+ pub fn LLVMGetTypeContext(Ty: TypeRef) -> ContextRef;
+
+ /* Operations on integer types */
+ pub fn LLVMInt1TypeInContext(C: ContextRef) -> TypeRef;
+ pub fn LLVMInt8TypeInContext(C: ContextRef) -> TypeRef;
+ pub fn LLVMInt16TypeInContext(C: ContextRef) -> TypeRef;
+ pub fn LLVMInt32TypeInContext(C: ContextRef) -> TypeRef;
+ pub fn LLVMInt64TypeInContext(C: ContextRef) -> TypeRef;
+ pub fn LLVMIntTypeInContext(C: ContextRef, NumBits: c_uint)
+ -> TypeRef;
+
+ pub fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint;
+
+ /* Operations on real types */
+ pub fn LLVMFloatTypeInContext(C: ContextRef) -> TypeRef;
+ pub fn LLVMDoubleTypeInContext(C: ContextRef) -> TypeRef;
+ pub fn LLVMX86FP80TypeInContext(C: ContextRef) -> TypeRef;
+ pub fn LLVMFP128TypeInContext(C: ContextRef) -> TypeRef;
+ pub fn LLVMPPCFP128TypeInContext(C: ContextRef) -> TypeRef;
+
+ /* Operations on function types */
+ pub fn LLVMFunctionType(ReturnType: TypeRef,
+ ParamTypes: *const TypeRef,
+ ParamCount: c_uint,
+ IsVarArg: Bool)
+ -> TypeRef;
+ pub fn LLVMIsFunctionVarArg(FunctionTy: TypeRef) -> Bool;
+ pub fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef;
+ pub fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint;
+ pub fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *const TypeRef);
+
+ /* Operations on struct types */
+ pub fn LLVMStructTypeInContext(C: ContextRef,
+ ElementTypes: *const TypeRef,
+ ElementCount: c_uint,
+ Packed: Bool)
+ -> TypeRef;
+ pub fn LLVMCountStructElementTypes(StructTy: TypeRef) -> c_uint;
+ pub fn LLVMGetStructElementTypes(StructTy: TypeRef,
+ Dest: *mut TypeRef);
+ pub fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool;
+
+ /* Operations on array, pointer, and vector types (sequence types) */
+ pub fn LLVMRustArrayType(ElementType: TypeRef, ElementCount: u64) -> TypeRef;
+ pub fn LLVMPointerType(ElementType: TypeRef, AddressSpace: c_uint)
+ -> TypeRef;
+ pub fn LLVMVectorType(ElementType: TypeRef, ElementCount: c_uint)
+ -> TypeRef;
+
+ pub fn LLVMGetElementType(Ty: TypeRef) -> TypeRef;
+ pub fn LLVMGetArrayLength(ArrayTy: TypeRef) -> c_uint;
+ pub fn LLVMGetPointerAddressSpace(PointerTy: TypeRef) -> c_uint;
+ pub fn LLVMGetPointerToGlobal(EE: ExecutionEngineRef, V: ValueRef)
+ -> *const ();
+ pub fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint;
+
+ /* Operations on other types */
+ pub fn LLVMVoidTypeInContext(C: ContextRef) -> TypeRef;
+ pub fn LLVMLabelTypeInContext(C: ContextRef) -> TypeRef;
+ pub fn LLVMMetadataTypeInContext(C: ContextRef) -> TypeRef;
+
+ /* Operations on all values */
+ pub fn LLVMTypeOf(Val: ValueRef) -> TypeRef;
+ pub fn LLVMGetValueName(Val: ValueRef) -> *const c_char;
+ pub fn LLVMSetValueName(Val: ValueRef, Name: *const c_char);
+ pub fn LLVMDumpValue(Val: ValueRef);
+ pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
+ pub fn LLVMHasMetadata(Val: ValueRef) -> c_int;
+ pub fn LLVMGetMetadata(Val: ValueRef, KindID: c_uint) -> ValueRef;
+ pub fn LLVMSetMetadata(Val: ValueRef, KindID: c_uint, Node: ValueRef);
+
+ /* Operations on Uses */
+ pub fn LLVMGetFirstUse(Val: ValueRef) -> UseRef;
+ pub fn LLVMGetNextUse(U: UseRef) -> UseRef;
+ pub fn LLVMGetUser(U: UseRef) -> ValueRef;
+ pub fn LLVMGetUsedValue(U: UseRef) -> ValueRef;
+
+ /* Operations on Users */
+ pub fn LLVMGetNumOperands(Val: ValueRef) -> c_int;
+ pub fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
+ pub fn LLVMSetOperand(Val: ValueRef, Index: c_uint, Op: ValueRef);
+
+ /* Operations on constants of any type */
+ pub fn LLVMConstNull(Ty: TypeRef) -> ValueRef;
+ /* all zeroes */
+ pub fn LLVMConstAllOnes(Ty: TypeRef) -> ValueRef;
+ pub fn LLVMConstICmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstFCmp(Pred: c_ushort, V1: ValueRef, V2: ValueRef)
+ -> ValueRef;
+ /* only for int/vector */
+ pub fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
+ pub fn LLVMIsConstant(Val: ValueRef) -> Bool;
+ pub fn LLVMIsNull(Val: ValueRef) -> Bool;
+ pub fn LLVMIsUndef(Val: ValueRef) -> Bool;
+ pub fn LLVMConstPointerNull(Ty: TypeRef) -> ValueRef;
+
+ /* Operations on metadata */
+ pub fn LLVMMDStringInContext(C: ContextRef,
+ Str: *const c_char,
+ SLen: c_uint)
+ -> ValueRef;
+ pub fn LLVMMDNodeInContext(C: ContextRef,
+ Vals: *const ValueRef,
+ Count: c_uint)
+ -> ValueRef;
+ pub fn LLVMAddNamedMetadataOperand(M: ModuleRef,
+ Str: *const c_char,
+ Val: ValueRef);
+
+ /* Operations on scalar constants */
+ pub fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool)
+ -> ValueRef;
+ pub fn LLVMConstIntOfString(IntTy: TypeRef, Text: *const c_char, Radix: u8)
+ -> ValueRef;
+ pub fn LLVMConstIntOfStringAndSize(IntTy: TypeRef,
+ Text: *const c_char,
+ SLen: c_uint,
+ Radix: u8)
+ -> ValueRef;
+ pub fn LLVMConstReal(RealTy: TypeRef, N: f64) -> ValueRef;
+ pub fn LLVMConstRealOfString(RealTy: TypeRef, Text: *const c_char)
+ -> ValueRef;
+ pub fn LLVMConstRealOfStringAndSize(RealTy: TypeRef,
+ Text: *const c_char,
+ SLen: c_uint)
+ -> ValueRef;
+ pub fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
+ pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
+
+
+ /* Operations on composite constants */
+ pub fn LLVMConstStringInContext(C: ContextRef,
+ Str: *const c_char,
+ Length: c_uint,
+ DontNullTerminate: Bool)
+ -> ValueRef;
+ pub fn LLVMConstStructInContext(C: ContextRef,
+ ConstantVals: *const ValueRef,
+ Count: c_uint,
+ Packed: Bool)
+ -> ValueRef;
+
+ pub fn LLVMConstArray(ElementTy: TypeRef,
+ ConstantVals: *const ValueRef,
+ Length: c_uint)
+ -> ValueRef;
+ pub fn LLVMConstVector(ScalarConstantVals: *const ValueRef, Size: c_uint)
+ -> ValueRef;
+
+ /* Constant expressions */
+ pub fn LLVMAlignOf(Ty: TypeRef) -> ValueRef;
+ pub fn LLVMSizeOf(Ty: TypeRef) -> ValueRef;
+ pub fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef;
+ pub fn LLVMConstNSWNeg(ConstantVal: ValueRef) -> ValueRef;
+ pub fn LLVMConstNUWNeg(ConstantVal: ValueRef) -> ValueRef;
+ pub fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef;
+ pub fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef;
+ pub fn LLVMConstAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstNSWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstNUWAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstFAdd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstNSWSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstNUWSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstFSub(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstNSWMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstNUWMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstFMul(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstUDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstSDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstExactSDiv(LHSConstant: ValueRef,
+ RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstFDiv(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstURem(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstSRem(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstFRem(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstAnd(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstOr(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstXor(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstShl(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstLShr(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstAShr(LHSConstant: ValueRef, RHSConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstGEP(ConstantVal: ValueRef,
+ ConstantIndices: *const ValueRef,
+ NumIndices: c_uint)
+ -> ValueRef;
+ pub fn LLVMConstInBoundsGEP(ConstantVal: ValueRef,
+ ConstantIndices: *const ValueRef,
+ NumIndices: c_uint)
+ -> ValueRef;
+ pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstSExt(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstFPTrunc(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstFPExt(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstZExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstSExtOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstTruncOrBitCast(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstIntCast(ConstantVal: ValueRef,
+ ToType: TypeRef,
+ isSigned: Bool)
+ -> ValueRef;
+ pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: TypeRef)
+ -> ValueRef;
+ pub fn LLVMConstSelect(ConstantCondition: ValueRef,
+ ConstantIfTrue: ValueRef,
+ ConstantIfFalse: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstExtractElement(VectorConstant: ValueRef,
+ IndexConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstInsertElement(VectorConstant: ValueRef,
+ ElementValueConstant: ValueRef,
+ IndexConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstShuffleVector(VectorAConstant: ValueRef,
+ VectorBConstant: ValueRef,
+ MaskConstant: ValueRef)
+ -> ValueRef;
+ pub fn LLVMConstExtractValue(AggConstant: ValueRef,
+ IdxList: *const c_uint,
+ NumIdx: c_uint)
+ -> ValueRef;
+ pub fn LLVMConstInsertValue(AggConstant: ValueRef,
+ ElementValueConstant: ValueRef,
+ IdxList: *const c_uint,
+ NumIdx: c_uint)
+ -> ValueRef;
+ pub fn LLVMConstInlineAsm(Ty: TypeRef,
+ AsmString: *const c_char,
+ Constraints: *const c_char,
+ HasSideEffects: Bool,
+ IsAlignStack: Bool)
+ -> ValueRef;
+ pub fn LLVMBlockAddress(F: ValueRef, BB: BasicBlockRef) -> ValueRef;
+
+
+
+ /* Operations on global variables, functions, and aliases (globals) */
+ pub fn LLVMGetGlobalParent(Global: ValueRef) -> ModuleRef;
+ pub fn LLVMIsDeclaration(Global: ValueRef) -> Bool;
+ pub fn LLVMGetLinkage(Global: ValueRef) -> c_uint;
+ pub fn LLVMSetLinkage(Global: ValueRef, Link: c_uint);
+ pub fn LLVMGetSection(Global: ValueRef) -> *const c_char;
+ pub fn LLVMSetSection(Global: ValueRef, Section: *const c_char);
+ pub fn LLVMGetVisibility(Global: ValueRef) -> c_uint;
+ pub fn LLVMSetVisibility(Global: ValueRef, Viz: c_uint);
+ pub fn LLVMGetAlignment(Global: ValueRef) -> c_uint;
+ pub fn LLVMSetAlignment(Global: ValueRef, Bytes: c_uint);
+
+
+ /* Operations on global variables */
+ pub fn LLVMAddGlobal(M: ModuleRef, Ty: TypeRef, Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMAddGlobalInAddressSpace(M: ModuleRef,
+ Ty: TypeRef,
+ Name: *const c_char,
+ AddressSpace: c_uint)
+ -> ValueRef;
+ pub fn LLVMGetNamedGlobal(M: ModuleRef, Name: *const c_char) -> ValueRef;
+ pub fn LLVMGetFirstGlobal(M: ModuleRef) -> ValueRef;
+ pub fn LLVMGetLastGlobal(M: ModuleRef) -> ValueRef;
+ pub fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef;
+ pub fn LLVMGetPreviousGlobal(GlobalVar: ValueRef) -> ValueRef;
+ pub fn LLVMDeleteGlobal(GlobalVar: ValueRef);
+ pub fn LLVMGetInitializer(GlobalVar: ValueRef) -> ValueRef;
+ pub fn LLVMSetInitializer(GlobalVar: ValueRef,
+ ConstantVal: ValueRef);
+ pub fn LLVMIsThreadLocal(GlobalVar: ValueRef) -> Bool;
+ pub fn LLVMSetThreadLocal(GlobalVar: ValueRef, IsThreadLocal: Bool);
+ pub fn LLVMIsGlobalConstant(GlobalVar: ValueRef) -> Bool;
+ pub fn LLVMSetGlobalConstant(GlobalVar: ValueRef, IsConstant: Bool);
+
+ /* Operations on aliases */
+ pub fn LLVMAddAlias(M: ModuleRef,
+ Ty: TypeRef,
+ Aliasee: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+
+ /* Operations on functions */
+ pub fn LLVMAddFunction(M: ModuleRef,
+ Name: *const c_char,
+ FunctionTy: TypeRef)
+ -> ValueRef;
+ pub fn LLVMGetNamedFunction(M: ModuleRef, Name: *const c_char) -> ValueRef;
+ pub fn LLVMGetFirstFunction(M: ModuleRef) -> ValueRef;
+ pub fn LLVMGetLastFunction(M: ModuleRef) -> ValueRef;
+ pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
+ pub fn LLVMGetPreviousFunction(Fn: ValueRef) -> ValueRef;
+ pub fn LLVMDeleteFunction(Fn: ValueRef);
+ pub fn LLVMGetOrInsertFunction(M: ModuleRef,
+ Name: *const c_char,
+ FunctionTy: TypeRef)
+ -> ValueRef;
+ pub fn LLVMGetIntrinsicID(Fn: ValueRef) -> c_uint;
+ pub fn LLVMGetFunctionCallConv(Fn: ValueRef) -> c_uint;
+ pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
+ pub fn LLVMGetGC(Fn: ValueRef) -> *const c_char;
+ pub fn LLVMSetGC(Fn: ValueRef, Name: *const c_char);
+ pub fn LLVMAddFunctionAttribute(Fn: ValueRef, index: c_uint, PA: uint64_t);
+ pub fn LLVMAddFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
+ pub fn LLVMRemoveFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
+ pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong;
+
+ /* Operations on parameters */
+ pub fn LLVMCountParams(Fn: ValueRef) -> c_uint;
+ pub fn LLVMGetParams(Fn: ValueRef, Params: *const ValueRef);
+ pub fn LLVMGetParam(Fn: ValueRef, Index: c_uint) -> ValueRef;
+ pub fn LLVMGetParamParent(Inst: ValueRef) -> ValueRef;
+ pub fn LLVMGetFirstParam(Fn: ValueRef) -> ValueRef;
+ pub fn LLVMGetLastParam(Fn: ValueRef) -> ValueRef;
+ pub fn LLVMGetNextParam(Arg: ValueRef) -> ValueRef;
+ pub fn LLVMGetPreviousParam(Arg: ValueRef) -> ValueRef;
+ pub fn LLVMAddAttribute(Arg: ValueRef, PA: c_uint);
+ pub fn LLVMRemoveAttribute(Arg: ValueRef, PA: c_uint);
+ pub fn LLVMGetAttribute(Arg: ValueRef) -> c_uint;
+ pub fn LLVMSetParamAlignment(Arg: ValueRef, align: c_uint);
+
+ /* Operations on basic blocks */
+ pub fn LLVMBasicBlockAsValue(BB: BasicBlockRef) -> ValueRef;
+ pub fn LLVMValueIsBasicBlock(Val: ValueRef) -> Bool;
+ pub fn LLVMValueAsBasicBlock(Val: ValueRef) -> BasicBlockRef;
+ pub fn LLVMGetBasicBlockParent(BB: BasicBlockRef) -> ValueRef;
+ pub fn LLVMCountBasicBlocks(Fn: ValueRef) -> c_uint;
+ pub fn LLVMGetBasicBlocks(Fn: ValueRef, BasicBlocks: *const ValueRef);
+ pub fn LLVMGetFirstBasicBlock(Fn: ValueRef) -> BasicBlockRef;
+ pub fn LLVMGetLastBasicBlock(Fn: ValueRef) -> BasicBlockRef;
+ pub fn LLVMGetNextBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
+ pub fn LLVMGetPreviousBasicBlock(BB: BasicBlockRef) -> BasicBlockRef;
+ pub fn LLVMGetEntryBasicBlock(Fn: ValueRef) -> BasicBlockRef;
+
+ pub fn LLVMAppendBasicBlockInContext(C: ContextRef,
+ Fn: ValueRef,
+ Name: *const c_char)
+ -> BasicBlockRef;
+ pub fn LLVMInsertBasicBlockInContext(C: ContextRef,
+ BB: BasicBlockRef,
+ Name: *const c_char)
+ -> BasicBlockRef;
+ pub fn LLVMDeleteBasicBlock(BB: BasicBlockRef);
+
+ pub fn LLVMMoveBasicBlockAfter(BB: BasicBlockRef,
+ MoveAfter: BasicBlockRef);
+
+ pub fn LLVMMoveBasicBlockBefore(BB: BasicBlockRef,
+ MoveBefore: BasicBlockRef);
+
+ /* Operations on instructions */
+ pub fn LLVMGetInstructionParent(Inst: ValueRef) -> BasicBlockRef;
+ pub fn LLVMGetFirstInstruction(BB: BasicBlockRef) -> ValueRef;
+ pub fn LLVMGetLastInstruction(BB: BasicBlockRef) -> ValueRef;
+ pub fn LLVMGetNextInstruction(Inst: ValueRef) -> ValueRef;
+ pub fn LLVMGetPreviousInstruction(Inst: ValueRef) -> ValueRef;
+ pub fn LLVMInstructionEraseFromParent(Inst: ValueRef);
+
+ /* Operations on call sites */
+ pub fn LLVMSetInstructionCallConv(Instr: ValueRef, CC: c_uint);
+ pub fn LLVMGetInstructionCallConv(Instr: ValueRef) -> c_uint;
+ pub fn LLVMAddInstrAttribute(Instr: ValueRef,
+ index: c_uint,
+ IA: c_uint);
+ pub fn LLVMRemoveInstrAttribute(Instr: ValueRef,
+ index: c_uint,
+ IA: c_uint);
+ pub fn LLVMSetInstrParamAlignment(Instr: ValueRef,
+ index: c_uint,
+ align: c_uint);
+ pub fn LLVMAddCallSiteAttribute(Instr: ValueRef,
+ index: c_uint,
+ Val: uint64_t);
+
+ /* Operations on call instructions (only) */
+ pub fn LLVMIsTailCall(CallInst: ValueRef) -> Bool;
+ pub fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool);
+
+ /* Operations on load/store instructions (only) */
+ pub fn LLVMGetVolatile(MemoryAccessInst: ValueRef) -> Bool;
+ pub fn LLVMSetVolatile(MemoryAccessInst: ValueRef, volatile: Bool);
+
+ /* Operations on phi nodes */
+ pub fn LLVMAddIncoming(PhiNode: ValueRef,
+ IncomingValues: *const ValueRef,
+ IncomingBlocks: *const BasicBlockRef,
+ Count: c_uint);
+ pub fn LLVMCountIncoming(PhiNode: ValueRef) -> c_uint;
+ pub fn LLVMGetIncomingValue(PhiNode: ValueRef, Index: c_uint)
+ -> ValueRef;
+ pub fn LLVMGetIncomingBlock(PhiNode: ValueRef, Index: c_uint)
+ -> BasicBlockRef;
+
+ /* Instruction builders */
+ pub fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef;
+ pub fn LLVMPositionBuilder(Builder: BuilderRef,
+ Block: BasicBlockRef,
+ Instr: ValueRef);
+ pub fn LLVMPositionBuilderBefore(Builder: BuilderRef,
+ Instr: ValueRef);
+ pub fn LLVMPositionBuilderAtEnd(Builder: BuilderRef,
+ Block: BasicBlockRef);
+ pub fn LLVMGetInsertBlock(Builder: BuilderRef) -> BasicBlockRef;
+ pub fn LLVMClearInsertionPosition(Builder: BuilderRef);
+ pub fn LLVMInsertIntoBuilder(Builder: BuilderRef, Instr: ValueRef);
+ pub fn LLVMInsertIntoBuilderWithName(Builder: BuilderRef,
+ Instr: ValueRef,
+ Name: *const c_char);
+ pub fn LLVMDisposeBuilder(Builder: BuilderRef);
+ pub fn LLVMDisposeExecutionEngine(EE: ExecutionEngineRef);
+
+ /* Metadata */
+ pub fn LLVMSetCurrentDebugLocation(Builder: BuilderRef, L: ValueRef);
+ pub fn LLVMGetCurrentDebugLocation(Builder: BuilderRef) -> ValueRef;
+ pub fn LLVMSetInstDebugLocation(Builder: BuilderRef, Inst: ValueRef);
+
+ /* Terminators */
+ pub fn LLVMBuildRetVoid(B: BuilderRef) -> ValueRef;
+ pub fn LLVMBuildRet(B: BuilderRef, V: ValueRef) -> ValueRef;
+ pub fn LLVMBuildAggregateRet(B: BuilderRef,
+ RetVals: *const ValueRef,
+ N: c_uint)
+ -> ValueRef;
+ pub fn LLVMBuildBr(B: BuilderRef, Dest: BasicBlockRef) -> ValueRef;
+ pub fn LLVMBuildCondBr(B: BuilderRef,
+ If: ValueRef,
+ Then: BasicBlockRef,
+ Else: BasicBlockRef)
+ -> ValueRef;
+ pub fn LLVMBuildSwitch(B: BuilderRef,
+ V: ValueRef,
+ Else: BasicBlockRef,
+ NumCases: c_uint)
+ -> ValueRef;
+ pub fn LLVMBuildIndirectBr(B: BuilderRef,
+ Addr: ValueRef,
+ NumDests: c_uint)
+ -> ValueRef;
+ pub fn LLVMBuildInvoke(B: BuilderRef,
+ Fn: ValueRef,
+ Args: *const ValueRef,
+ NumArgs: c_uint,
+ Then: BasicBlockRef,
+ Catch: BasicBlockRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildLandingPad(B: BuilderRef,
+ Ty: TypeRef,
+ PersFn: ValueRef,
+ NumClauses: c_uint,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildResume(B: BuilderRef, Exn: ValueRef) -> ValueRef;
+ pub fn LLVMBuildUnreachable(B: BuilderRef) -> ValueRef;
+
+ /* Add a case to the switch instruction */
+ pub fn LLVMAddCase(Switch: ValueRef,
+ OnVal: ValueRef,
+ Dest: BasicBlockRef);
+
+ /* Add a destination to the indirectbr instruction */
+ pub fn LLVMAddDestination(IndirectBr: ValueRef, Dest: BasicBlockRef);
+
+ /* Add a clause to the landing pad instruction */
+ pub fn LLVMAddClause(LandingPad: ValueRef, ClauseVal: ValueRef);
+
+ /* Set the cleanup on a landing pad instruction */
+ pub fn LLVMSetCleanup(LandingPad: ValueRef, Val: Bool);
+
+ /* Arithmetic */
+ pub fn LLVMBuildAdd(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildNSWAdd(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildNUWAdd(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildFAdd(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildSub(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildNSWSub(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildNUWSub(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildFSub(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildMul(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildNSWMul(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildNUWMul(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildFMul(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildUDiv(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildSDiv(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildExactSDiv(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildFDiv(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildURem(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildSRem(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildFRem(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildShl(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildLShr(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildAShr(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildAnd(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildOr(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildXor(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildBinOp(B: BuilderRef,
+ Op: Opcode,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildNSWNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildNUWNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildFNeg(B: BuilderRef, V: ValueRef, Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildNot(B: BuilderRef, V: ValueRef, Name: *const c_char)
+ -> ValueRef;
+
+ /* Memory */
+ pub fn LLVMBuildMalloc(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildArrayMalloc(B: BuilderRef,
+ Ty: TypeRef,
+ Val: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildAlloca(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildArrayAlloca(B: BuilderRef,
+ Ty: TypeRef,
+ Val: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildFree(B: BuilderRef, PointerVal: ValueRef) -> ValueRef;
+ pub fn LLVMBuildLoad(B: BuilderRef,
+ PointerVal: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+
+ pub fn LLVMBuildStore(B: BuilderRef, Val: ValueRef, Ptr: ValueRef)
+ -> ValueRef;
+
+ pub fn LLVMBuildGEP(B: BuilderRef,
+ Pointer: ValueRef,
+ Indices: *const ValueRef,
+ NumIndices: c_uint,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildInBoundsGEP(B: BuilderRef,
+ Pointer: ValueRef,
+ Indices: *const ValueRef,
+ NumIndices: c_uint,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildStructGEP(B: BuilderRef,
+ Pointer: ValueRef,
+ Idx: c_uint,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildGlobalString(B: BuilderRef,
+ Str: *const c_char,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildGlobalStringPtr(B: BuilderRef,
+ Str: *const c_char,
+ Name: *const c_char)
+ -> ValueRef;
+
+ /* Casts */
+ pub fn LLVMBuildTrunc(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildZExt(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildSExt(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildFPToUI(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildFPToSI(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildUIToFP(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildSIToFP(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildFPTrunc(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildFPExt(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildPtrToInt(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildIntToPtr(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildBitCast(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildZExtOrBitCast(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildSExtOrBitCast(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildTruncOrBitCast(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildCast(B: BuilderRef,
+ Op: Opcode,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char) -> ValueRef;
+ pub fn LLVMBuildPointerCast(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildIntCast(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildFPCast(B: BuilderRef,
+ Val: ValueRef,
+ DestTy: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+
+ /* Comparisons */
+ pub fn LLVMBuildICmp(B: BuilderRef,
+ Op: c_uint,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildFCmp(B: BuilderRef,
+ Op: c_uint,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+
+ /* Miscellaneous instructions */
+ pub fn LLVMBuildPhi(B: BuilderRef, Ty: TypeRef, Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildCall(B: BuilderRef,
+ Fn: ValueRef,
+ Args: *const ValueRef,
+ NumArgs: c_uint,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildSelect(B: BuilderRef,
+ If: ValueRef,
+ Then: ValueRef,
+ Else: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildVAArg(B: BuilderRef,
+ list: ValueRef,
+ Ty: TypeRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildExtractElement(B: BuilderRef,
+ VecVal: ValueRef,
+ Index: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildInsertElement(B: BuilderRef,
+ VecVal: ValueRef,
+ EltVal: ValueRef,
+ Index: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildShuffleVector(B: BuilderRef,
+ V1: ValueRef,
+ V2: ValueRef,
+ Mask: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildExtractValue(B: BuilderRef,
+ AggVal: ValueRef,
+ Index: c_uint,
+ Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildInsertValue(B: BuilderRef,
+ AggVal: ValueRef,
+ EltVal: ValueRef,
+ Index: c_uint,
+ Name: *const c_char)
+ -> ValueRef;
+
+ pub fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *const c_char)
+ -> ValueRef;
+ pub fn LLVMBuildPtrDiff(B: BuilderRef,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Name: *const c_char)
+ -> ValueRef;
+
+ /* Atomic Operations */
+ pub fn LLVMBuildAtomicLoad(B: BuilderRef,
+ PointerVal: ValueRef,
+ Name: *const c_char,
+ Order: AtomicOrdering,
+ Alignment: c_uint)
+ -> ValueRef;
+
+ pub fn LLVMBuildAtomicStore(B: BuilderRef,
+ Val: ValueRef,
+ Ptr: ValueRef,
+ Order: AtomicOrdering,
+ Alignment: c_uint)
+ -> ValueRef;
+
+ pub fn LLVMBuildAtomicCmpXchg(B: BuilderRef,
+ LHS: ValueRef,
+ CMP: ValueRef,
+ RHS: ValueRef,
+ Order: AtomicOrdering,
+ FailureOrder: AtomicOrdering)
+ -> ValueRef;
+ pub fn LLVMBuildAtomicRMW(B: BuilderRef,
+ Op: AtomicBinOp,
+ LHS: ValueRef,
+ RHS: ValueRef,
+ Order: AtomicOrdering,
+ SingleThreaded: Bool)
+ -> ValueRef;
+
+ pub fn LLVMBuildAtomicFence(B: BuilderRef, Order: AtomicOrdering);
+
+
+ /* Selected entries from the downcasts. */
+ pub fn LLVMIsATerminatorInst(Inst: ValueRef) -> ValueRef;
+ pub fn LLVMIsAStoreInst(Inst: ValueRef) -> ValueRef;
+
+ /** Writes a module to the specified path. Returns 0 on success. */
+ pub fn LLVMWriteBitcodeToFile(M: ModuleRef, Path: *const c_char) -> c_int;
+
+ /** Creates target data from a target layout string. */
+ pub fn LLVMCreateTargetData(StringRep: *const c_char) -> TargetDataRef;
+ /// Adds the target data to the given pass manager. The pass manager
+ /// references the target data only weakly.
+ pub fn LLVMAddTargetData(TD: TargetDataRef, PM: PassManagerRef);
+ /** Number of bytes clobbered when doing a Store to *T. */
+ pub fn LLVMStoreSizeOfType(TD: TargetDataRef, Ty: TypeRef)
+ -> c_ulonglong;
+
+ /** Number of bytes clobbered when doing a Store to *T. */
+ pub fn LLVMSizeOfTypeInBits(TD: TargetDataRef, Ty: TypeRef)
+ -> c_ulonglong;
+
+ /** Distance between successive elements in an array of T.
+ Includes ABI padding. */
+ pub fn LLVMABISizeOfType(TD: TargetDataRef, Ty: TypeRef) -> c_uint;
+
+ /** Returns the preferred alignment of a type. */
+ pub fn LLVMPreferredAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
+ -> c_uint;
+ /** Returns the minimum alignment of a type. */
+ pub fn LLVMABIAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
+ -> c_uint;
+
+ /// Computes the byte offset of the indexed struct element for a
+ /// target.
+ pub fn LLVMOffsetOfElement(TD: TargetDataRef,
+ StructTy: TypeRef,
+ Element: c_uint)
+ -> c_ulonglong;
+
+ /**
+ * Returns the minimum alignment of a type when part of a call frame.
+ */
+ pub fn LLVMCallFrameAlignmentOfType(TD: TargetDataRef, Ty: TypeRef)
+ -> c_uint;
+
+ /** Disposes target data. */
+ pub fn LLVMDisposeTargetData(TD: TargetDataRef);
+
+ /** Creates a pass manager. */
+ pub fn LLVMCreatePassManager() -> PassManagerRef;
+
+ /** Creates a function-by-function pass manager */
+ pub fn LLVMCreateFunctionPassManagerForModule(M: ModuleRef)
+ -> PassManagerRef;
+
+ /** Disposes a pass manager. */
+ pub fn LLVMDisposePassManager(PM: PassManagerRef);
+
+ /** Runs a pass manager on a module. */
+ pub fn LLVMRunPassManager(PM: PassManagerRef, M: ModuleRef) -> Bool;
+
+ /** Runs the function passes on the provided function. */
+ pub fn LLVMRunFunctionPassManager(FPM: PassManagerRef, F: ValueRef)
+ -> Bool;
+
+ /** Initializes all the function passes scheduled in the manager */
+ pub fn LLVMInitializeFunctionPassManager(FPM: PassManagerRef) -> Bool;
+
+ /** Finalizes all the function passes scheduled in the manager */
+ pub fn LLVMFinalizeFunctionPassManager(FPM: PassManagerRef) -> Bool;
+
+ pub fn LLVMInitializePasses();
+
+ /** Adds a verification pass. */
+ pub fn LLVMAddVerifierPass(PM: PassManagerRef);
+
+ pub fn LLVMAddGlobalOptimizerPass(PM: PassManagerRef);
+ pub fn LLVMAddIPSCCPPass(PM: PassManagerRef);
+ pub fn LLVMAddDeadArgEliminationPass(PM: PassManagerRef);
+ pub fn LLVMAddInstructionCombiningPass(PM: PassManagerRef);
+ pub fn LLVMAddCFGSimplificationPass(PM: PassManagerRef);
+ pub fn LLVMAddFunctionInliningPass(PM: PassManagerRef);
+ pub fn LLVMAddFunctionAttrsPass(PM: PassManagerRef);
+ pub fn LLVMAddScalarReplAggregatesPass(PM: PassManagerRef);
+ pub fn LLVMAddScalarReplAggregatesPassSSA(PM: PassManagerRef);
+ pub fn LLVMAddJumpThreadingPass(PM: PassManagerRef);
+ pub fn LLVMAddConstantPropagationPass(PM: PassManagerRef);
+ pub fn LLVMAddReassociatePass(PM: PassManagerRef);
+ pub fn LLVMAddLoopRotatePass(PM: PassManagerRef);
+ pub fn LLVMAddLICMPass(PM: PassManagerRef);
+ pub fn LLVMAddLoopUnswitchPass(PM: PassManagerRef);
+ pub fn LLVMAddLoopDeletionPass(PM: PassManagerRef);
+ pub fn LLVMAddLoopUnrollPass(PM: PassManagerRef);
+ pub fn LLVMAddGVNPass(PM: PassManagerRef);
+ pub fn LLVMAddMemCpyOptPass(PM: PassManagerRef);
+ pub fn LLVMAddSCCPPass(PM: PassManagerRef);
+ pub fn LLVMAddDeadStoreEliminationPass(PM: PassManagerRef);
+ pub fn LLVMAddStripDeadPrototypesPass(PM: PassManagerRef);
+ pub fn LLVMAddConstantMergePass(PM: PassManagerRef);
+ pub fn LLVMAddArgumentPromotionPass(PM: PassManagerRef);
+ pub fn LLVMAddTailCallEliminationPass(PM: PassManagerRef);
+ pub fn LLVMAddIndVarSimplifyPass(PM: PassManagerRef);
+ pub fn LLVMAddAggressiveDCEPass(PM: PassManagerRef);
+ pub fn LLVMAddGlobalDCEPass(PM: PassManagerRef);
+ pub fn LLVMAddCorrelatedValuePropagationPass(PM: PassManagerRef);
+ pub fn LLVMAddPruneEHPass(PM: PassManagerRef);
+ pub fn LLVMAddSimplifyLibCallsPass(PM: PassManagerRef);
+ pub fn LLVMAddLoopIdiomPass(PM: PassManagerRef);
+ pub fn LLVMAddEarlyCSEPass(PM: PassManagerRef);
+ pub fn LLVMAddTypeBasedAliasAnalysisPass(PM: PassManagerRef);
+ pub fn LLVMAddBasicAliasAnalysisPass(PM: PassManagerRef);
+
+ pub fn LLVMPassManagerBuilderCreate() -> PassManagerBuilderRef;
+ pub fn LLVMPassManagerBuilderDispose(PMB: PassManagerBuilderRef);
+ pub fn LLVMPassManagerBuilderSetOptLevel(PMB: PassManagerBuilderRef,
+ OptimizationLevel: c_uint);
+ pub fn LLVMPassManagerBuilderSetSizeLevel(PMB: PassManagerBuilderRef,
+ Value: Bool);
+ pub fn LLVMPassManagerBuilderSetDisableUnitAtATime(
+ PMB: PassManagerBuilderRef,
+ Value: Bool);
+ pub fn LLVMPassManagerBuilderSetDisableUnrollLoops(
+ PMB: PassManagerBuilderRef,
+ Value: Bool);
+ pub fn LLVMPassManagerBuilderSetDisableSimplifyLibCalls(
+ PMB: PassManagerBuilderRef,
+ Value: Bool);
+ pub fn LLVMPassManagerBuilderUseInlinerWithThreshold(
+ PMB: PassManagerBuilderRef,
+ threshold: c_uint);
+ pub fn LLVMPassManagerBuilderPopulateModulePassManager(
+ PMB: PassManagerBuilderRef,
+ PM: PassManagerRef);
+
+ pub fn LLVMPassManagerBuilderPopulateFunctionPassManager(
+ PMB: PassManagerBuilderRef,
+ PM: PassManagerRef);
+ pub fn LLVMPassManagerBuilderPopulateLTOPassManager(
+ PMB: PassManagerBuilderRef,
+ PM: PassManagerRef,
+ Internalize: Bool,
+ RunInliner: Bool);
+
+ /** Destroys a memory buffer. */
+ pub fn LLVMDisposeMemoryBuffer(MemBuf: MemoryBufferRef);
+
+
+ /* Stuff that's in rustllvm/ because it's not upstream yet. */
+
+ /** Opens an object file. */
+ pub fn LLVMCreateObjectFile(MemBuf: MemoryBufferRef) -> ObjectFileRef;
+ /** Closes an object file. */
+ pub fn LLVMDisposeObjectFile(ObjFile: ObjectFileRef);
+
+ /** Enumerates the sections in an object file. */
+ pub fn LLVMGetSections(ObjFile: ObjectFileRef) -> SectionIteratorRef;
+ /** Destroys a section iterator. */
+ pub fn LLVMDisposeSectionIterator(SI: SectionIteratorRef);
+ /** Returns true if the section iterator is at the end of the section
+ list: */
+ pub fn LLVMIsSectionIteratorAtEnd(ObjFile: ObjectFileRef,
+ SI: SectionIteratorRef)
+ -> Bool;
+ /** Moves the section iterator to point to the next section. */
+ pub fn LLVMMoveToNextSection(SI: SectionIteratorRef);
+ /** Returns the current section size. */
+ pub fn LLVMGetSectionSize(SI: SectionIteratorRef) -> c_ulonglong;
+ /** Returns the current section contents as a string buffer. */
+ pub fn LLVMGetSectionContents(SI: SectionIteratorRef) -> *const c_char;
+
+ /** Reads the given file and returns it as a memory buffer. Use
+ LLVMDisposeMemoryBuffer() to get rid of it. */
+ pub fn LLVMRustCreateMemoryBufferWithContentsOfFile(Path: *const c_char)
+ -> MemoryBufferRef;
+ /** Borrows the contents of the memory buffer (doesn't copy it) */
+ pub fn LLVMCreateMemoryBufferWithMemoryRange(InputData: *const c_char,
+ InputDataLength: size_t,
+ BufferName: *const c_char,
+ RequiresNull: Bool)
+ -> MemoryBufferRef;
+ pub fn LLVMCreateMemoryBufferWithMemoryRangeCopy(InputData: *const c_char,
+ InputDataLength: size_t,
+ BufferName: *const c_char)
+ -> MemoryBufferRef;
+
+ pub fn LLVMIsMultithreaded() -> Bool;
+ pub fn LLVMStartMultithreaded() -> Bool;
+
+ /** Returns a string describing the last error caused by an LLVMRust*
+ call. */
+ pub fn LLVMRustGetLastError() -> *const c_char;
+
+ /// Print the pass timings since static dtors aren't picking them up.
+ pub fn LLVMRustPrintPassTimings();
+
+ pub fn LLVMStructCreateNamed(C: ContextRef, Name: *const c_char) -> TypeRef;
+
+ pub fn LLVMStructSetBody(StructTy: TypeRef,
+ ElementTypes: *const TypeRef,
+ ElementCount: c_uint,
+ Packed: Bool);
+
+ pub fn LLVMConstNamedStruct(S: TypeRef,
+ ConstantVals: *const ValueRef,
+ Count: c_uint)
+ -> ValueRef;
+
+ /** Enables LLVM debug output. */
+ pub fn LLVMSetDebug(Enabled: c_int);
+
+ /** Prepares inline assembly. */
+ pub fn LLVMInlineAsm(Ty: TypeRef,
+ AsmString: *const c_char,
+ Constraints: *const c_char,
+ SideEffects: Bool,
+ AlignStack: Bool,
+ Dialect: c_uint)
+ -> ValueRef;
+
+ pub static LLVMRustDebugMetadataVersion: u32;
+
+ pub fn LLVMRustAddModuleFlag(M: ModuleRef,
+ name: *const c_char,
+ value: u32);
+
+ pub fn LLVMDIBuilderCreate(M: ModuleRef) -> DIBuilderRef;
+
+ pub fn LLVMDIBuilderDispose(Builder: DIBuilderRef);
+
+ pub fn LLVMDIBuilderFinalize(Builder: DIBuilderRef);
+
+ pub fn LLVMDIBuilderCreateCompileUnit(Builder: DIBuilderRef,
+ Lang: c_uint,
+ File: *const c_char,
+ Dir: *const c_char,
+ Producer: *const c_char,
+ isOptimized: bool,
+ Flags: *const c_char,
+ RuntimeVer: c_uint,
+ SplitName: *const c_char);
+
+ pub fn LLVMDIBuilderCreateFile(Builder: DIBuilderRef,
+ Filename: *const c_char,
+ Directory: *const c_char)
+ -> DIFile;
+
+ pub fn LLVMDIBuilderCreateSubroutineType(Builder: DIBuilderRef,
+ File: DIFile,
+ ParameterTypes: DIArray)
+ -> DICompositeType;
+
+ pub fn LLVMDIBuilderCreateFunction(Builder: DIBuilderRef,
+ Scope: DIDescriptor,
+ Name: *const c_char,
+ LinkageName: *const c_char,
+ File: DIFile,
+ LineNo: c_uint,
+ Ty: DIType,
+ isLocalToUnit: bool,
+ isDefinition: bool,
+ ScopeLine: c_uint,
+ Flags: c_uint,
+ isOptimized: bool,
+ Fn: ValueRef,
+ TParam: ValueRef,
+ Decl: ValueRef)
+ -> DISubprogram;
+
+ pub fn LLVMDIBuilderCreateBasicType(Builder: DIBuilderRef,
+ Name: *const c_char,
+ SizeInBits: c_ulonglong,
+ AlignInBits: c_ulonglong,
+ Encoding: c_uint)
+ -> DIBasicType;
+
+ pub fn LLVMDIBuilderCreatePointerType(Builder: DIBuilderRef,
+ PointeeTy: DIType,
+ SizeInBits: c_ulonglong,
+ AlignInBits: c_ulonglong,
+ Name: *const c_char)
+ -> DIDerivedType;
+
+ pub fn LLVMDIBuilderCreateStructType(Builder: DIBuilderRef,
+ Scope: DIDescriptor,
+ Name: *const c_char,
+ File: DIFile,
+ LineNumber: c_uint,
+ SizeInBits: c_ulonglong,
+ AlignInBits: c_ulonglong,
+ Flags: c_uint,
+ DerivedFrom: DIType,
+ Elements: DIArray,
+ RunTimeLang: c_uint,
+ VTableHolder: ValueRef,
+ UniqueId: *const c_char)
+ -> DICompositeType;
+
+ pub fn LLVMDIBuilderCreateMemberType(Builder: DIBuilderRef,
+ Scope: DIDescriptor,
+ Name: *const c_char,
+ File: DIFile,
+ LineNo: c_uint,
+ SizeInBits: c_ulonglong,
+ AlignInBits: c_ulonglong,
+ OffsetInBits: c_ulonglong,
+ Flags: c_uint,
+ Ty: DIType)
+ -> DIDerivedType;
+
+ pub fn LLVMDIBuilderCreateLexicalBlock(Builder: DIBuilderRef,
+ Scope: DIDescriptor,
+ File: DIFile,
+ Line: c_uint,
+ Col: c_uint,
+ Discriminator: c_uint)
+ -> DILexicalBlock;
+
+ pub fn LLVMDIBuilderCreateStaticVariable(Builder: DIBuilderRef,
+ Context: DIDescriptor,
+ Name: *const c_char,
+ LinkageName: *const c_char,
+ File: DIFile,
+ LineNo: c_uint,
+ Ty: DIType,
+ isLocalToUnit: bool,
+ Val: ValueRef,
+ Decl: ValueRef)
+ -> DIGlobalVariable;
+
+ pub fn LLVMDIBuilderCreateLocalVariable(Builder: DIBuilderRef,
+ Tag: c_uint,
+ Scope: DIDescriptor,
+ Name: *const c_char,
+ File: DIFile,
+ LineNo: c_uint,
+ Ty: DIType,
+ AlwaysPreserve: bool,
+ Flags: c_uint,
+ ArgNo: c_uint)
+ -> DIVariable;
+
+ pub fn LLVMDIBuilderCreateArrayType(Builder: DIBuilderRef,
+ Size: c_ulonglong,
+ AlignInBits: c_ulonglong,
+ Ty: DIType,
+ Subscripts: DIArray)
+ -> DIType;
+
+ pub fn LLVMDIBuilderCreateVectorType(Builder: DIBuilderRef,
+ Size: c_ulonglong,
+ AlignInBits: c_ulonglong,
+ Ty: DIType,
+ Subscripts: DIArray)
+ -> DIType;
+
+ pub fn LLVMDIBuilderGetOrCreateSubrange(Builder: DIBuilderRef,
+ Lo: c_longlong,
+ Count: c_longlong)
+ -> DISubrange;
+
+ pub fn LLVMDIBuilderGetOrCreateArray(Builder: DIBuilderRef,
+ Ptr: *const DIDescriptor,
+ Count: c_uint)
+ -> DIArray;
+
+ pub fn LLVMDIBuilderInsertDeclareAtEnd(Builder: DIBuilderRef,
+ Val: ValueRef,
+ VarInfo: DIVariable,
+ InsertAtEnd: BasicBlockRef)
+ -> ValueRef;
+
+ pub fn LLVMDIBuilderInsertDeclareBefore(Builder: DIBuilderRef,
+ Val: ValueRef,
+ VarInfo: DIVariable,
+ InsertBefore: ValueRef)
+ -> ValueRef;
+
+ pub fn LLVMDIBuilderCreateEnumerator(Builder: DIBuilderRef,
+ Name: *const c_char,
+ Val: c_ulonglong)
+ -> ValueRef;
+
+ pub fn LLVMDIBuilderCreateEnumerationType(Builder: DIBuilderRef,
+ Scope: ValueRef,
+ Name: *const c_char,
+ File: ValueRef,
+ LineNumber: c_uint,
+ SizeInBits: c_ulonglong,
+ AlignInBits: c_ulonglong,
+ Elements: ValueRef,
+ ClassType: ValueRef)
+ -> ValueRef;
+
+ pub fn LLVMDIBuilderCreateUnionType(Builder: DIBuilderRef,
+ Scope: ValueRef,
+ Name: *const c_char,
+ File: ValueRef,
+ LineNumber: c_uint,
+ SizeInBits: c_ulonglong,
+ AlignInBits: c_ulonglong,
+ Flags: c_uint,
+ Elements: ValueRef,
+ RunTimeLang: c_uint,
+ UniqueId: *const c_char)
+ -> ValueRef;
+
+ pub fn LLVMSetUnnamedAddr(GlobalVar: ValueRef, UnnamedAddr: Bool);
+
+ pub fn LLVMDIBuilderCreateTemplateTypeParameter(Builder: DIBuilderRef,
+ Scope: ValueRef,
+ Name: *const c_char,
+ Ty: ValueRef,
+ File: ValueRef,
+ LineNo: c_uint,
+ ColumnNo: c_uint)
+ -> ValueRef;
+
+ pub fn LLVMDIBuilderCreateOpDeref(IntType: TypeRef) -> ValueRef;
+
+ pub fn LLVMDIBuilderCreateOpPlus(IntType: TypeRef) -> ValueRef;
+
+ pub fn LLVMDIBuilderCreateComplexVariable(Builder: DIBuilderRef,
+ Tag: c_uint,
+ Scope: ValueRef,
+ Name: *const c_char,
+ File: ValueRef,
+ LineNo: c_uint,
+ Ty: ValueRef,
+ AddrOps: *const ValueRef,
+ AddrOpsCount: c_uint,
+ ArgNo: c_uint)
+ -> ValueRef;
+
+ pub fn LLVMDIBuilderCreateNameSpace(Builder: DIBuilderRef,
+ Scope: ValueRef,
+ Name: *const c_char,
+ File: ValueRef,
+ LineNo: c_uint)
+ -> ValueRef;
+
+ pub fn LLVMDICompositeTypeSetTypeArray(CompositeType: ValueRef, TypeArray: ValueRef);
+ pub fn LLVMTypeToString(Type: TypeRef) -> *const c_char;
+ pub fn LLVMValueToString(value_ref: ValueRef) -> *const c_char;
+
+ pub fn LLVMIsAArgument(value_ref: ValueRef) -> ValueRef;
+
+ pub fn LLVMIsAAllocaInst(value_ref: ValueRef) -> ValueRef;
+
+ pub fn LLVMInitializeX86TargetInfo();
+ pub fn LLVMInitializeX86Target();
+ pub fn LLVMInitializeX86TargetMC();
+ pub fn LLVMInitializeX86AsmPrinter();
+ pub fn LLVMInitializeX86AsmParser();
+ pub fn LLVMInitializeARMTargetInfo();
+ pub fn LLVMInitializeARMTarget();
+ pub fn LLVMInitializeARMTargetMC();
+ pub fn LLVMInitializeARMAsmPrinter();
+ pub fn LLVMInitializeARMAsmParser();
+ pub fn LLVMInitializeMipsTargetInfo();
+ pub fn LLVMInitializeMipsTarget();
+ pub fn LLVMInitializeMipsTargetMC();
+ pub fn LLVMInitializeMipsAsmPrinter();
+ pub fn LLVMInitializeMipsAsmParser();
+
+ pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: *const c_char) -> bool;
+ pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
+ CPU: *const c_char,
+ Features: *const c_char,
+ Model: CodeGenModel,
+ Reloc: RelocMode,
+ Level: CodeGenOptLevel,
+ EnableSegstk: bool,
+ UseSoftFP: bool,
+ NoFramePointerElim: bool,
+ FunctionSections: bool,
+ DataSections: bool) -> TargetMachineRef;
+ pub fn LLVMRustDisposeTargetMachine(T: TargetMachineRef);
+ pub fn LLVMRustAddAnalysisPasses(T: TargetMachineRef,
+ PM: PassManagerRef,
+ M: ModuleRef);
+ pub fn LLVMRustAddBuilderLibraryInfo(PMB: PassManagerBuilderRef,
+ M: ModuleRef,
+ DisableSimplifyLibCalls: bool);
+ pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef, M: ModuleRef,
+ DisableSimplifyLibCalls: bool);
+ pub fn LLVMRustRunFunctionPassManager(PM: PassManagerRef, M: ModuleRef);
+ pub fn LLVMRustWriteOutputFile(T: TargetMachineRef,
+ PM: PassManagerRef,
+ M: ModuleRef,
+ Output: *const c_char,
+ FileType: FileType) -> bool;
+ pub fn LLVMRustPrintModule(PM: PassManagerRef,
+ M: ModuleRef,
+ Output: *const c_char);
+ pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char);
+ pub fn LLVMRustPrintPasses();
+ pub fn LLVMRustSetNormalizedTarget(M: ModuleRef, triple: *const c_char);
+ pub fn LLVMRustAddAlwaysInlinePass(P: PassManagerBuilderRef,
+ AddLifetimes: bool);
+ pub fn LLVMRustLinkInExternalBitcode(M: ModuleRef,
+ bc: *const c_char,
+ len: size_t) -> bool;
+ pub fn LLVMRustRunRestrictionPass(M: ModuleRef,
+ syms: *const *const c_char,
+ len: size_t);
+ pub fn LLVMRustMarkAllFunctionsNounwind(M: ModuleRef);
+
+ pub fn LLVMRustOpenArchive(path: *const c_char) -> ArchiveRef;
+ pub fn LLVMRustArchiveReadSection(AR: ArchiveRef, name: *const c_char,
+ out_len: *mut size_t) -> *const c_char;
+ pub fn LLVMRustDestroyArchive(AR: ArchiveRef);
+
+ pub fn LLVMRustSetDLLExportStorageClass(V: ValueRef);
+ pub fn LLVMVersionMajor() -> c_int;
+ pub fn LLVMVersionMinor() -> c_int;
+
+ pub fn LLVMRustGetSectionName(SI: SectionIteratorRef,
+ data: *mut *const c_char) -> c_int;
+}
+
+pub fn SetInstructionCallConv(instr: ValueRef, cc: CallConv) {
+ unsafe {
+ LLVMSetInstructionCallConv(instr, cc as c_uint);
+ }
+}
+pub fn SetFunctionCallConv(fn_: ValueRef, cc: CallConv) {
+ unsafe {
+ LLVMSetFunctionCallConv(fn_, cc as c_uint);
+ }
+}
+pub fn SetLinkage(global: ValueRef, link: Linkage) {
+ unsafe {
+ LLVMSetLinkage(global, link as c_uint);
+ }
+}
+
+pub fn SetUnnamedAddr(global: ValueRef, unnamed: bool) {
+ unsafe {
+ LLVMSetUnnamedAddr(global, unnamed as Bool);
+ }
+}
+
+pub fn set_thread_local(global: ValueRef, is_thread_local: bool) {
+ unsafe {
+ LLVMSetThreadLocal(global, is_thread_local as Bool);
+ }
+}
+
+pub fn ConstICmp(pred: IntPredicate, v1: ValueRef, v2: ValueRef) -> ValueRef {
+ unsafe {
+ LLVMConstICmp(pred as c_ushort, v1, v2)
+ }
+}
+pub fn ConstFCmp(pred: RealPredicate, v1: ValueRef, v2: ValueRef) -> ValueRef {
+ unsafe {
+ LLVMConstFCmp(pred as c_ushort, v1, v2)
+ }
+}
+
+pub fn SetFunctionAttribute(fn_: ValueRef, attr: Attribute) {
+ unsafe {
+ LLVMAddFunctionAttribute(fn_, FunctionIndex as c_uint, attr as uint64_t)
+ }
+}
+
+/* Memory-managed interface to target data. */
+
+pub struct TargetData {
+ pub lltd: TargetDataRef
+}
+
+impl Drop for TargetData {
+ fn drop(&mut self) {
+ unsafe {
+ LLVMDisposeTargetData(self.lltd);
+ }
+ }
+}
+
+pub fn mk_target_data(string_rep: &str) -> TargetData {
+ TargetData {
+ lltd: string_rep.with_c_str(|buf| {
+ unsafe { LLVMCreateTargetData(buf) }
+ })
+ }
+}
+
+/* Memory-managed interface to object files. */
+
+pub struct ObjectFile {
+ pub llof: ObjectFileRef,
+}
+
+impl ObjectFile {
+ // This will take ownership of llmb
+ pub fn new(llmb: MemoryBufferRef) -> Option<ObjectFile> {
+ unsafe {
+ let llof = LLVMCreateObjectFile(llmb);
+ if llof as int == 0 {
+ // LLVMCreateObjectFile took ownership of llmb
+ return None
+ }
+
+ Some(ObjectFile {
+ llof: llof,
+ })
+ }
+ }
+}
+
+impl Drop for ObjectFile {
+ fn drop(&mut self) {
+ unsafe {
+ LLVMDisposeObjectFile(self.llof);
+ }
+ }
+}
+
+/* Memory-managed interface to section iterators. */
+
+pub struct SectionIter {
+ pub llsi: SectionIteratorRef
+}
+
+impl Drop for SectionIter {
+ fn drop(&mut self) {
+ unsafe {
+ LLVMDisposeSectionIterator(self.llsi);
+ }
+ }
+}
+
+pub fn mk_section_iter(llof: ObjectFileRef) -> SectionIter {
+ unsafe {
+ SectionIter {
+ llsi: LLVMGetSections(llof)
+ }
+ }
+}
+
+// FIXME #15460 - create a public function that actually calls our
+// static LLVM symbols. Otherwise the linker will just throw llvm
+// away. We're just calling lots of stuff until we transitively get
+// all of LLVM. This is worse than anything.
+pub unsafe fn static_link_hack_this_sucks() {
+ LLVMInitializePasses();
+
+ LLVMInitializeX86TargetInfo();
+ LLVMInitializeX86Target();
+ LLVMInitializeX86TargetMC();
+ LLVMInitializeX86AsmPrinter();
+ LLVMInitializeX86AsmParser();
+
+ LLVMInitializeARMTargetInfo();
+ LLVMInitializeARMTarget();
+ LLVMInitializeARMTargetMC();
+ LLVMInitializeARMAsmPrinter();
+ LLVMInitializeARMAsmParser();
+
+ LLVMInitializeMipsTargetInfo();
+ LLVMInitializeMipsTarget();
+ LLVMInitializeMipsTargetMC();
+ LLVMInitializeMipsAsmPrinter();
+ LLVMInitializeMipsAsmParser();
+
+ LLVMRustSetLLVMOptions(0 as c_int,
+ 0 as *const _);
+
+ LLVMPassManagerBuilderPopulateModulePassManager(0 as *mut _, 0 as *mut _);
+ LLVMPassManagerBuilderPopulateLTOPassManager(0 as *mut _, 0 as *mut _, False, False);
+ LLVMPassManagerBuilderPopulateFunctionPassManager(0 as *mut _, 0 as *mut _);
+ LLVMPassManagerBuilderSetOptLevel(0 as *mut _, 0 as c_uint);
+ LLVMPassManagerBuilderUseInlinerWithThreshold(0 as *mut _, 0 as c_uint);
+ LLVMWriteBitcodeToFile(0 as *mut _, 0 as *const _);
+ LLVMPassManagerBuilderCreate();
+ LLVMPassManagerBuilderDispose(0 as *mut _);
+
+ LLVMRustLinkInExternalBitcode(0 as *mut _, 0 as *const _, 0 as size_t);
+
+ LLVMLinkInJIT();
+ LLVMLinkInMCJIT();
+ LLVMLinkInInterpreter();
+
+ extern {
+ fn LLVMLinkInJIT();
+ fn LLVMLinkInMCJIT();
+ fn LLVMLinkInInterpreter();
+ }
+}
+
+// The module containing the native LLVM dependencies, generated by the build system
+// Note that this must come after the rustllvm extern declaration so that
+// parts of LLVM that rustllvm depends on aren't thrown away by the linker.
+// Works to the above fix for #15460 to ensure LLVM dependencies that
+// are only used by rustllvm don't get stripped by the linker.
+mod llvmdeps;
+
cx.inlined.borrow_mut().get_mut_ref().insert(did);
ret.push(clean::Item {
source: clean::Span::empty(),
- name: Some(fqn.last().unwrap().to_str()),
+ name: Some(fqn.last().unwrap().to_string()),
attrs: load_attrs(tcx, did),
inner: inner,
visibility: Some(ast::Public),
match cx.maybe_typed {
core::Typed(ref tcx) => {
let fqn = csearch::get_item_path(tcx, did);
- let fqn = fqn.move_iter().map(|i| i.to_str()).collect();
+ let fqn = fqn.move_iter().map(|i| i.to_string()).collect();
cx.external_paths.borrow_mut().get_mut_ref().insert(did, (fqn, kind));
}
core::NotTyped(..) => {}
// Figure out the name of this crate
let input = driver::FileInput(cx.src.clone());
- let t_outputs = driver::build_output_filenames(&input,
- &None,
- &None,
- self.attrs.as_slice(),
- cx.sess());
- let id = link::find_crate_id(self.attrs.as_slice(),
- t_outputs.out_filestem.as_slice());
+ let name = link::find_crate_name(None, self.attrs.as_slice(), &input);
// Clean the crate, translating the entire libsyntax AST to one that is
// understood by rustdoc.
}
Crate {
- name: id.name.to_string(),
+ name: name.to_string(),
module: Some(module),
externs: externs,
primitives: primitives,
List(s.get().to_string(), l.clean().move_iter().collect())
}
ast::MetaNameValue(ref s, ref v) => {
- NameValue(s.get().to_string(), lit_to_str(v))
+ NameValue(s.get().to_string(), lit_to_string(v))
}
}
}
}
fn external_path(name: &str, substs: &subst::Substs) -> Path {
- let lifetimes = substs.regions().get_vec(subst::TypeSpace)
+ let lifetimes = substs.regions().get_slice(subst::TypeSpace)
.iter()
.filter_map(|v| v.clean())
.collect();
- let types = substs.types.get_vec(subst::TypeSpace).clean();
+ let types = Vec::from_slice(substs.types.get_slice(subst::TypeSpace));
+ let types = types.clean();
Path {
global: false,
segments: vec![PathSegment {
external_path("Share", &empty)),
};
let fqn = csearch::get_item_path(tcx, did);
- let fqn = fqn.move_iter().map(|i| i.to_str()).collect();
+ let fqn = fqn.move_iter().map(|i| i.to_string()).collect();
cx.external_paths.borrow_mut().get_mut_ref().insert(did,
(fqn, TypeTrait));
TraitBound(ResolvedPath {
core::NotTyped(_) => return RegionBound,
};
let fqn = csearch::get_item_path(tcx, self.def_id);
- let fqn = fqn.move_iter().map(|i| i.to_str())
+ let fqn = fqn.move_iter().map(|i| i.to_string())
.collect::<Vec<String>>();
let path = external_path(fqn.last().unwrap().as_slice(),
&self.substs);
// is implicit.
let space = {
- if !self.types.get_vec(subst::FnSpace).is_empty() ||
- !self.regions.get_vec(subst::FnSpace).is_empty()
+ if !self.types.is_empty_in(subst::FnSpace) ||
+ !self.regions.is_empty_in(subst::FnSpace)
{
subst::FnSpace
} else {
};
Generics {
- type_params: self.types.get_vec(space).clean(),
- lifetimes: self.regions.get_vec(space).clean(),
+ type_params: Vec::from_slice(self.types.get_slice(space)).clean(),
+ lifetimes: Vec::from_slice(self.regions.get_slice(space)).clean(),
}
}
}
impl Clean<Item> for ast::Method {
fn clean(&self) -> Item {
- let inputs = match self.explicit_self.node {
- ast::SelfStatic => self.decl.inputs.as_slice(),
- _ => self.decl.inputs.slice_from(1)
+ let fn_decl = ast_util::method_fn_decl(self);
+ let inputs = match ast_util::method_explicit_self(self).node {
+ ast::SelfStatic => fn_decl.inputs.as_slice(),
+ _ => fn_decl.inputs.slice_from(1)
};
let decl = FnDecl {
inputs: Arguments {
values: inputs.iter().map(|x| x.clean()).collect(),
},
- output: (self.decl.output.clean()),
- cf: self.decl.cf.clean(),
+ output: (fn_decl.output.clean()),
+ cf: fn_decl.cf.clean(),
attrs: Vec::new()
};
Item {
- name: Some(self.ident.clean()),
+ name: Some(ast_util::method_ident(self).clean()),
attrs: self.attrs.clean().move_iter().collect(),
source: self.span.clean(),
def_id: ast_util::local_def(self.id),
- visibility: self.vis.clean(),
+ visibility: ast_util::method_vis(self).clean(),
stability: get_stability(ast_util::local_def(self.id)),
inner: MethodItem(Method {
- generics: self.generics.clean(),
- self_: self.explicit_self.node.clean(),
- fn_style: self.fn_style.clone(),
+ generics: ast_util::method_generics(self).clean(),
+ self_: ast_util::method_explicit_self(self).node.clean(),
+ fn_style: ast_util::method_fn_style(self).clone(),
decl: decl,
}),
}
fn clean(&self) -> SelfTy {
match *self {
ast::SelfStatic => SelfStatic,
- ast::SelfValue => SelfValue,
- ast::SelfUniq => SelfOwned,
- ast::SelfRegion(lt, mt) => SelfBorrowed(lt.clean(), mt.clean()),
+ ast::SelfValue(_) => SelfValue,
+ ast::SelfUniq(_) => SelfOwned,
+ ast::SelfRegion(lt, mt, _) => SelfBorrowed(lt.clean(), mt.clean()),
}
}
}
return None
}
- pub fn to_str(&self) -> &'static str {
+ pub fn to_string(&self) -> &'static str {
match *self {
Int => "int",
I8 => "i8",
pub fn to_url_str(&self) -> &'static str {
match *self {
Unit => "unit",
- other => other.to_str(),
+ other => other.to_string(),
}
}
lifetimes: Vec::new(), type_params: Vec::new()
},
decl: (ast_util::local_def(0), &fty.sig).clean(),
- abi: fty.abi.to_str(),
+ abi: fty.abi.to_string(),
}),
ty::ty_closure(ref fty) => {
let decl = box ClosureDecl {
ty::ty_trait(box ty::TyTrait { def_id: did, ref substs, .. }) => {
let fqn = csearch::get_item_path(get_cx().tcx(), did);
let fqn: Vec<String> = fqn.move_iter().map(|i| {
- i.to_str()
+ i.to_string()
}).collect();
let kind = match ty::get(*self).sty {
ty::ty_struct(..) => TypeStruct,
ty::ty_trait(..) => TypeTrait,
_ => TypeEnum,
};
- let path = external_path(fqn.last().unwrap().to_str().as_slice(),
+ let path = external_path(fqn.last().unwrap().to_string().as_slice(),
substs);
get_cx().external_paths.borrow_mut().get_mut_ref()
.insert(did, (fqn, kind));
name: Some(name.clean()),
attrs: Vec::new(),
visibility: Some(ast::Public),
- stability: get_stability(self.id),
// FIXME: this is not accurate, we need an id for
// the specific field but we're using the id
- // for the whole variant. Nothing currently
- // uses this so we should be good for now.
+ // for the whole variant. Thus we read the
+ // stability from the whole variant as well.
+ // Struct variants are experimental and need
+ // more infrastructure work before we can get
+ // at the needed information here.
def_id: self.id,
+ stability: get_stability(self.id),
inner: StructFieldItem(
TypedStructField(ty.clean())
)
visibility: Some(ast::Public),
def_id: self.id,
inner: VariantItem(Variant { kind: kind }),
- stability: None,
+ stability: get_stability(self.id),
}
}
}
}
}
-fn path_to_str(p: &ast::Path) -> String {
+fn path_to_string(p: &ast::Path) -> String {
let mut s = String::new();
let mut first = true;
for i in p.segments.iter().map(|x| token::get_ident(x.identifier)) {
type_params: Vec::new(),
},
decl: self.decl.clean(),
- abi: self.abi.to_str(),
+ abi: self.abi.to_string(),
}
}
}
source: self.span.clean(),
def_id: ast_util::local_def(self.id),
visibility: self.vis.clean(),
- stability: None,
+ stability: get_stability(ast_util::local_def(self.id)),
inner: inner,
}
}
}
}
-fn lit_to_str(lit: &ast::Lit) -> String {
+fn lit_to_string(lit: &ast::Lit) -> String {
match lit.node {
ast::LitStr(ref st, _) => st.get().to_string(),
ast::LitBinary(ref data) => format!("{:?}", data.as_slice()),
res
},
ast::LitChar(c) => format!("'{}'", c),
- ast::LitInt(i, _t) => i.to_str(),
- ast::LitUint(u, _t) => u.to_str(),
- ast::LitIntUnsuffixed(i) => i.to_str(),
+ ast::LitInt(i, _t) => i.to_string(),
+ ast::LitUint(u, _t) => u.to_string(),
+ ast::LitIntUnsuffixed(i) => i.to_string(),
ast::LitFloat(ref f, _t) => f.get().to_string(),
ast::LitFloatUnsuffixed(ref f) => f.get().to_string(),
- ast::LitBool(b) => b.to_str(),
+ ast::LitBool(b) => b.to_string(),
ast::LitNil => "".to_string(),
}
}
PatWild => "_".to_string(),
PatWildMulti => "..".to_string(),
PatIdent(_, ref p, _) => token::get_ident(p.node).get().to_string(),
- PatEnum(ref p, _) => path_to_str(p),
- PatStruct(..) => fail!("tried to get argument name from pat_struct, \
- which is not allowed in function arguments"),
- PatTup(..) => "(tuple arg NYI)".to_string(),
+ PatEnum(ref p, _) => path_to_string(p),
+ PatStruct(ref name, ref fields, etc) => {
+ format!("{} {{ {}{} }}", path_to_string(name),
+ fields.iter().map(|fp|
+ format!("{}: {}", fp.ident.as_str(), name_from_pat(&*fp.pat)))
+ .collect::<Vec<String>>().connect(", "),
+ if etc { ", ..." } else { "" }
+ )
+ },
+ PatTup(ref elts) => format!("({})", elts.iter().map(|p| name_from_pat(&**p))
+ .collect::<Vec<String>>().connect(", ")),
PatBox(p) => name_from_pat(&*p),
PatRegion(p) => name_from_pat(&*p),
PatLit(..) => {
use rustc::{driver, middle};
use rustc::middle::{privacy, ty};
use rustc::lint;
+use rustc::back::link;
use syntax::ast;
use syntax::parse::token;
let codemap = syntax::codemap::CodeMap::new();
- let diagnostic_handler = syntax::diagnostic::default_handler(syntax::diagnostic::Auto);
+ let diagnostic_handler = syntax::diagnostic::default_handler(syntax::diagnostic::Auto, None);
let span_diagnostic_handler =
syntax::diagnostic::mk_span_handler(diagnostic_handler, codemap);
}
let krate = phase_1_parse_input(&sess, cfg, &input);
+
+ let name = link::find_crate_name(Some(&sess), krate.attrs.as_slice(),
+ &input);
+
let (krate, ast_map)
- = phase_2_configure_and_expand(&sess, krate, &from_str("rustdoc").unwrap())
+ = phase_2_configure_and_expand(&sess, krate, name.as_slice())
.expect("phase_2_configure_and_expand aborted in rustdoc!");
let driver::driver::CrateAnalysis {
exported_items, public_items, ty_cx, ..
- } = phase_3_run_analysis_passes(sess, &krate, ast_map);
+ } = phase_3_run_analysis_passes(sess, &krate, ast_map, name);
debug!("crate: {:?}", krate);
(DocContext {
use syntax::ast_util;
use clean;
+use stability_summary::ModuleSummary;
use html::item_type;
use html::item_type::ItemType;
use html::render;
pub struct Method<'a>(pub &'a clean::SelfTy, pub &'a clean::FnDecl);
/// Similar to VisSpace, but used for mutability
pub struct MutableSpace(pub clean::Mutability);
+/// Similar to VisSpace, but used for mutability
+pub struct RawMutableSpace(pub clean::Mutability);
/// Wrapper struct for properly emitting the stability level.
pub struct Stability<'a>(pub &'a Option<clean::Stability>);
/// Wrapper struct for emitting the stability level concisely.
tybounds(f, typarams)
}
clean::Self(..) => f.write("Self".as_bytes()),
- clean::Primitive(prim) => primitive_link(f, prim, prim.to_str()),
+ clean::Primitive(prim) => primitive_link(f, prim, prim.to_string()),
clean::Closure(ref decl, ref region) => {
write!(f, "{style}{lifetimes}|{args}|{bounds}{arrow}",
style = FnStyleSpace(decl.fn_style),
} else {
let mut m = decl.bounds
.iter()
- .map(|s| s.to_str());
+ .map(|s| s.to_string());
format!(
": {}",
m.collect::<Vec<String>>().connect(" + "))
}
clean::Tuple(ref typs) => {
primitive_link(f, clean::PrimitiveTuple,
- format!("({:#})", typs).as_slice())
+ match typs.as_slice() {
+ [ref one] => format!("({},)", one),
+ many => format!("({:#})", many)
+ }.as_slice())
}
clean::Vector(ref t) => {
primitive_link(f, clean::Slice, format!("[{}]", **t).as_slice())
clean::Unique(ref t) => write!(f, "Box<{}>", **t),
clean::Managed(ref t) => write!(f, "Gc<{}>", **t),
clean::RawPointer(m, ref t) => {
- write!(f, "*{}{}", MutableSpace(m), **t)
+ write!(f, "*{}{}", RawMutableSpace(m), **t)
}
clean::BorrowedRef{ lifetime: ref l, mutability, type_: ref ty} => {
let lt = match *l {
}
}
+impl fmt::Show for RawMutableSpace {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ RawMutableSpace(clean::Immutable) => write!(f, "const "),
+ RawMutableSpace(clean::Mutable) => write!(f, "mut "),
+ }
+ }
+}
+
impl<'a> fmt::Show for Stability<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let Stability(stab) = *self;
match *stab {
Some(ref stability) => {
write!(f, "<a class='stability {lvl}' title='{reason}'>{lvl}</a>",
- lvl = stability.level.to_str(),
+ lvl = stability.level.to_string(),
reason = stability.text)
}
None => Ok(())
match *stab {
Some(ref stability) => {
write!(f, "<a class='stability {lvl}' title='{lvl}{colon}{reason}'></a>",
- lvl = stability.level.to_str(),
+ lvl = stability.level.to_string(),
colon = if stability.text.len() > 0 { ": " } else { "" },
reason = stability.text)
}
}
}
}
+
+impl fmt::Show for ModuleSummary {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt_inner<'a>(f: &mut fmt::Formatter,
+ context: &mut Vec<&'a str>,
+ m: &'a ModuleSummary)
+ -> fmt::Result {
+ let cnt = m.counts;
+ let tot = cnt.total();
+ if tot == 0 { return Ok(()) }
+
+ context.push(m.name.as_slice());
+ let path = context.connect("::");
+
+ // the total width of each row's stability summary, in pixels
+ let width = 500;
+
+ try!(write!(f, "<tr>"));
+ try!(write!(f, "<td class='summary'>\
+ <a class='summary' href='{}'>{}</a></td>",
+ Vec::from_slice(context.slice_from(1))
+ .append_one("index.html").connect("/"),
+ path));
+ try!(write!(f, "<td>"));
+ try!(write!(f, "<span class='summary Stable' \
+ style='width: {}px; display: inline-block'> </span>",
+ (width * cnt.stable)/tot));
+ try!(write!(f, "<span class='summary Unstable' \
+ style='width: {}px; display: inline-block'> </span>",
+ (width * cnt.unstable)/tot));
+ try!(write!(f, "<span class='summary Experimental' \
+ style='width: {}px; display: inline-block'> </span>",
+ (width * cnt.experimental)/tot));
+ try!(write!(f, "<span class='summary Deprecated' \
+ style='width: {}px; display: inline-block'> </span>",
+ (width * cnt.deprecated)/tot));
+ try!(write!(f, "<span class='summary Unmarked' \
+ style='width: {}px; display: inline-block'> </span>",
+ (width * cnt.unmarked)/tot));
+ try!(write!(f, "</td></tr>"));
+
+ for submodule in m.submodules.iter() {
+ try!(fmt_inner(f, context, submodule));
+ }
+ context.pop();
+ Ok(())
+ }
+
+ let mut context = Vec::new();
+
+ try!(write!(f,
+r"<h1 class='fqn'>Stability dashboard: crate <a class='mod' href='index.html'>{}</a></h1>
+This dashboard summarizes the stability levels for all of the public modules of
+the crate, according to the total number of items at each level in the module and its children:
+<blockquote>
+<a class='stability Stable'></a> stable,<br/>
+<a class='stability Unstable'></a> unstable,<br/>
+<a class='stability Experimental'></a> experimental,<br/>
+<a class='stability Deprecated'></a> deprecated,<br/>
+<a class='stability Unmarked'></a> unmarked
+</blockquote>
+The counts do not include methods or trait
+implementations that are visible only through a re-exported type.",
+self.name));
+ try!(write!(f, "<table>"))
+ try!(fmt_inner(f, &mut context, self));
+ write!(f, "</table>")
+ }
+}
use syntax::parse;
use syntax::parse::lexer;
-use syntax::codemap::{BytePos, Span};
use html::escape::Escape;
None => {}
}
try!(write!(out, "class='rust {}'>\n", class.unwrap_or("")));
- let mut last = BytePos(0);
let mut is_attribute = false;
let mut is_macro = false;
let mut is_macro_nonterminal = false;
loop {
let next = lexer.next_token();
- let test = if next.tok == t::EOF {lexer.pos} else {next.sp.lo};
-
- // The lexer consumes all whitespace and non-doc-comments when iterating
- // between tokens. If this token isn't directly adjacent to our last
- // token, then we need to emit the whitespace/comment.
- //
- // If the gap has any '/' characters then we consider the whole thing a
- // comment. This will classify some whitespace as a comment, but that
- // doesn't matter too much for syntax highlighting purposes.
- if test > last {
- let snip = sess.span_diagnostic.cm.span_to_snippet(Span {
- lo: last,
- hi: test,
- expn_info: None,
- }).unwrap();
- if snip.as_slice().contains("/") {
- try!(write!(out, "<span class='comment'>{}</span>",
- Escape(snip.as_slice())));
- } else {
- try!(write!(out, "{}", Escape(snip.as_slice())));
- }
- }
- last = next.sp.hi;
+
+ let snip = |sp| sess.span_diagnostic.cm.span_to_snippet(sp).unwrap();
+
if next.tok == t::EOF { break }
let klass = match next.tok {
+ t::WS => {
+ try!(write!(out, "{}", Escape(snip(next.sp).as_slice())));
+ continue
+ },
+ t::COMMENT => {
+ try!(write!(out, "<span class='comment'>{}</span>",
+ Escape(snip(next.sp).as_slice())));
+ continue
+ },
+ t::SHEBANG(s) => {
+ try!(write!(out, "{}", Escape(s.as_str())));
+ continue
+ },
// If this '&' token is directly adjacent to another token, assume
// that it's the address-of operator instead of the and-operator.
// This allows us to give all pointers their own class (`Box` and
// miscellaneous, no highlighting
t::DOT | t::DOTDOT | t::DOTDOTDOT | t::COMMA | t::SEMI |
t::COLON | t::MOD_SEP | t::LARROW | t::LPAREN |
- t::RPAREN | t::LBRACKET | t::LBRACE | t::RBRACE => "",
+ t::RPAREN | t::LBRACKET | t::LBRACE | t::RBRACE | t::QUESTION => "",
t::DOLLAR => {
if t::is_ident(&lexer.peek().tok) {
is_macro_nonterminal = true;
t::LIT_CHAR(..) | t::LIT_STR(..) | t::LIT_STR_RAW(..) => "string",
// number literals
- t::LIT_INT(..) | t::LIT_UINT(..) | t::LIT_INT_UNSUFFIXED(..) |
- t::LIT_FLOAT(..) | t::LIT_FLOAT_UNSUFFIXED(..) => "number",
+ t::LIT_INTEGER(..) | t::LIT_FLOAT(..) => "number",
// keywords are also included in the identifier set
t::IDENT(ident, _is_mod_sep) => {
<title>{title}</title>
- <link href='http://fonts.googleapis.com/css?family=Source+Code+Pro:400,600'
- rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="{root_path}main.css">
{favicon}
// Transform the contents of the header into a hyphenated string
let id = s.as_slice().words().map(|s| {
match s.to_ascii_opt() {
- Some(s) => s.to_lower().into_str(),
+ Some(s) => s.to_lower().into_string(),
None => s.to_string()
}
}).collect::<Vec<String>>().connect("-");
use externalfiles::ExternalHtml;
+use serialize::json;
+use serialize::Encodable;
use serialize::json::ToJson;
use syntax::ast;
use syntax::ast_util;
use html::layout;
use html::markdown::Markdown;
use html::markdown;
+use stability_summary;
/// Major driving force in all rustdoc rendering. This contains information
/// about where in the tree-like hierarchy rendering is occurring and controls
try!(mkdir(&cx.dst));
+ // Crawl the crate, building a summary of the stability levels. NOTE: this
+ // summary *must* be computed with the original `krate`; the folding below
+ // removes the impls from their modules.
+ let summary = stability_summary::build(&krate);
+
// Crawl the crate attributes looking for attributes which control how we're
// going to emit HTML
match krate.module.as_ref().map(|m| m.doc_list().unwrap_or(&[])) {
let krate = try!(render_sources(&mut cx, krate));
// And finally render the whole crate's documentation
- cx.krate(krate)
+ cx.krate(krate, summary)
}
fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::IoResult<String> {
}
try!(write!(&mut w, r#"[{:u},"{}","{}",{}"#,
item.ty, item.name, path,
- item.desc.to_json().to_str()));
+ item.desc.to_json().to_string()));
match item.parent {
Some(nodeid) => {
let pathid = *nodeid_to_pathid.find(&nodeid).unwrap();
include_bin!("static/FiraSans-Regular.woff")));
try!(write(cx.dst.join("FiraSans-Medium.woff"),
include_bin!("static/FiraSans-Medium.woff")));
- try!(write(cx.dst.join("Heuristica-Regular.woff"),
- include_bin!("static/Heuristica-Regular.woff")));
try!(write(cx.dst.join("Heuristica-Italic.woff"),
include_bin!("static/Heuristica-Italic.woff")));
- try!(write(cx.dst.join("Heuristica-Bold.woff"),
- include_bin!("static/Heuristica-Bold.woff")));
+ try!(write(cx.dst.join("SourceSerifPro-Regular.woff"),
+ include_bin!("static/SourceSerifPro-Regular.woff")));
+ try!(write(cx.dst.join("SourceSerifPro-Bold.woff"),
+ include_bin!("static/SourceSerifPro-Bold.woff")));
+ try!(write(cx.dst.join("SourceCodePro-Regular.woff"),
+ include_bin!("static/SourceCodePro-Regular.woff")));
+ try!(write(cx.dst.join("SourceCodePro-Semibold.woff"),
+ include_bin!("static/SourceCodePro-Semibold.woff")));
fn collect(path: &Path, krate: &str,
key: &str) -> io::IoResult<Vec<String>> {
///
/// This currently isn't parallelized, but it'd be pretty easy to add
/// parallelization to this function.
- fn krate(self, mut krate: clean::Crate) -> io::IoResult<()> {
+ fn krate(mut self, mut krate: clean::Crate,
+ stability: stability_summary::ModuleSummary) -> io::IoResult<()> {
let mut item = match krate.module.take() {
Some(i) => i,
None => return Ok(())
};
item.name = Some(krate.name);
+ // render stability dashboard
+ try!(self.recurse(stability.name.clone(), |this| {
+ let json_dst = &this.dst.join("stability.json");
+ let mut json_out = BufferedWriter::new(try!(File::create(json_dst)));
+ try!(stability.encode(&mut json::Encoder::new(&mut json_out)));
+
+ let title = stability.name.clone().append(" - Stability dashboard");
+ let page = layout::Page {
+ ty: "mod",
+ root_path: this.root_path.as_slice(),
+ title: title.as_slice(),
+ };
+ let html_dst = &this.dst.join("stability.html");
+ let mut html_out = BufferedWriter::new(try!(File::create(html_dst)));
+ layout::render(&mut html_out, &this.layout, &page,
+ &Sidebar{ cx: this, item: &item },
+ &stability)
+ }));
+
+ // render the crate documentation
let mut work = vec!((self, item));
loop {
match work.pop() {
None => break,
}
}
+
Ok(())
}
}
}
+
+
impl<'a> fmt::Show for Item<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
// Write the breadcrumb trail header for the top
// Write stability level
try!(write!(fmt, "{}", Stability(&self.item.stability)));
+ // Links to out-of-band information, i.e. src and stability dashboard
+ try!(write!(fmt, "<span class='out-of-band'>"));
+
+ // Write stability dashboard link
+ match self.item.inner {
+ clean::ModuleItem(ref m) if m.is_crate => {
+ try!(write!(fmt, "<a href='stability.html'>[stability dashboard]</a> "));
+ }
+ _ => {}
+ };
+
// Write `src` tag
//
// When this item is part of a `pub use` in a downstream crate, the
if self.cx.include_sources && !is_primitive {
match self.href() {
Some(l) => {
- try!(write!(fmt,
- "<a class='source' id='src-{}' \
- href='{}'>[src]</a>",
+ try!(write!(fmt, "<a id='src-{}' href='{}'>[src]</a>",
self.item.def_id.node, l));
}
None => {}
}
}
+
+ try!(write!(fmt, "</span>"));
+
try!(write!(fmt, "</h1>\n"));
match self.item.inner {
fn item_module(w: &mut fmt::Formatter, cx: &Context,
item: &clean::Item, items: &[clean::Item]) -> fmt::Result {
try!(document(w, item));
+
let mut indices = range(0, items.len()).filter(|i| {
!ignore_private_item(&items[*i])
}).collect::<Vec<uint>>();
}
}
}
+
write!(w, "</table>")
}
--- /dev/null
+Copyright (c) 2014, Mozilla Foundation https://mozilla.org/
+with Reserved Font Name Fira Sans.
+
+Copyright (c) 2014, Mozilla Foundation https://mozilla.org/
+with Reserved Font Name Fira Mono.
+
+Copyright (c) 2014, Telefonica S.A.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
--- /dev/null
+Copyright 1989, 1991 Adobe Systems Incorporated. All rights reserved.
+Utopia is either a registered trademark or trademark of Adobe Systems
+Incorporated in the United States and/or other countries. Used under
+license.
+
+Copyright 2006 Han The Thanh, Vntopia font family, http://vntex.sf.net
+
+Copyright (c) 2008-2012, Andrey V. Panov (panov@canopus.iacp.dvo.ru),
+with Reserved Font Name Heuristica.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
--- /dev/null
+Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+
+This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
--- /dev/null
+Copyright 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+
+This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff');
}
@font-face {
- font-family: 'Heuristica';
+ font-family: 'Source Serif Pro';
font-style: normal;
font-weight: 400;
- src: local('Heuristica Regular'), url("Heuristica-Regular.woff") format('woff');
+ src: local('Source Serif Pro'), url("SourceSerifPro-Regular.woff") format('woff');
}
@font-face {
- font-family: 'Heuristica';
+ font-family: 'Source Serif Pro';
font-style: italic;
font-weight: 400;
- src: local('Heuristica Italic'), url("Heuristica-Italic.woff") format('woff');
+ src: url("Heuristica-Italic.woff") format('woff');
}
@font-face {
- font-family: 'Heuristica';
+ font-family: 'Source Serif Pro';
font-style: normal;
font-weight: 700;
- src: local('Heuristica Bold'), url("Heuristica-Bold.woff") format('woff');
+ src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.woff") format('woff');
+}
+@font-face {
+ font-family: 'Source Code Pro';
+ font-style: normal;
+ font-weight: 400;
+ src: local('Source Code Pro'), url("SourceCodePro-Regular.woff") format('woff');
+}
+@font-face {
+ font-family: 'Source Code Pro';
+ font-style: normal;
+ font-weight: 600;
+ src: local('Source Code Pro Semibold'), url("SourceCodePro-Semibold.woff") format('woff');
}
@import "normalize.css";
body {
color: #333;
min-width: 500px;
- font: 15.5px/1.4 "Heuristica", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font: 16px/1.4 "Source Serif Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: 0;
position: relative;
padding: 10px 15px 20px 15px;
.docblock h2 { font-size: 1.15em; }
.docblock h3, .docblock h4, .docblock h5 { font-size: 1em; }
-.content .source {
+.content .out-of-band {
float: right;
font-size: 23px;
}
.stability.Locked { border-color: #0084B6; color: #00668c; }
.stability.Unmarked { border-color: #FFFFFF; }
+.summary {
+ padding-right: 0px;
+}
+.summary.Deprecated { background-color: #A071A8; }
+.summary.Experimental { background-color: #D46D6A; }
+.summary.Unstable { background-color: #D4B16A; }
+.summary.Stable { background-color: #54A759; }
+.summary.Unmarked { background-color: #FFFFFF; }
+
:target { background: #FDFFD3; }
/* Code highlighting */
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![crate_id = "rustdoc#0.11.0"]
+#![crate_name = "rustdoc"]
#![experimental]
#![desc = "rustdoc, the Rust documentation extractor"]
#![license = "MIT/ASL2"]
pub mod markdown;
pub mod passes;
pub mod plugins;
+pub mod stability_summary;
pub mod visit_ast;
pub mod test;
mod flock;
}
};
match json::from_reader(&mut input) {
- Err(s) => Err(s.to_str()),
+ Err(s) => Err(s.to_string()),
Ok(json::Object(obj)) => {
let mut obj = obj;
// Make sure the schema is what we expect
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! This module crawls a `clean::Crate` and produces a summarization of the
+//! stability levels within the crate. The summary contains the module
+//! hierarchy, with item counts for every stability level per module. A parent
+//! module's count includes its childrens's.
+
+use std::ops::Add;
+use std::num::Zero;
+use std::iter::AdditiveIterator;
+
+use syntax::attr::{Deprecated, Experimental, Unstable, Stable, Frozen, Locked};
+use syntax::ast::Public;
+
+use clean::{Crate, Item, ModuleItem, Module, StructItem, Struct, EnumItem, Enum};
+use clean::{ImplItem, Impl, TraitItem, Trait, TraitMethod, Provided, Required};
+use clean::{ViewItemItem, PrimitiveItem};
+
+#[deriving(Zero, Encodable, Decodable, PartialEq, Eq)]
+/// The counts for each stability level.
+pub struct Counts {
+ pub deprecated: uint,
+ pub experimental: uint,
+ pub unstable: uint,
+ pub stable: uint,
+ pub frozen: uint,
+ pub locked: uint,
+
+ /// No stability level, inherited or otherwise.
+ pub unmarked: uint,
+}
+
+impl Add<Counts, Counts> for Counts {
+ fn add(&self, other: &Counts) -> Counts {
+ Counts {
+ deprecated: self.deprecated + other.deprecated,
+ experimental: self.experimental + other.experimental,
+ unstable: self.unstable + other.unstable,
+ stable: self.stable + other.stable,
+ frozen: self.frozen + other.frozen,
+ locked: self.locked + other.locked,
+ unmarked: self.unmarked + other.unmarked,
+ }
+ }
+}
+
+impl Counts {
+ pub fn total(&self) -> uint {
+ self.deprecated + self.experimental + self.unstable + self.stable +
+ self.frozen + self.locked + self.unmarked
+ }
+}
+
+#[deriving(Encodable, Decodable, PartialEq, Eq)]
+/// A summarized module, which includes total counts and summarized chilcren
+/// modules.
+pub struct ModuleSummary {
+ pub name: String,
+ pub counts: Counts,
+ pub submodules: Vec<ModuleSummary>,
+}
+
+impl PartialOrd for ModuleSummary {
+ fn partial_cmp(&self, other: &ModuleSummary) -> Option<Ordering> {
+ self.name.partial_cmp(&other.name)
+ }
+}
+
+impl Ord for ModuleSummary {
+ fn cmp(&self, other: &ModuleSummary) -> Ordering {
+ self.name.cmp(&other.name)
+ }
+}
+
+// is the item considered publically visible?
+fn visible(item: &Item) -> bool {
+ match item.inner {
+ ImplItem(_) => true,
+ _ => item.visibility == Some(Public)
+ }
+}
+
+// Produce the summary for an arbitrary item. If the item is a module, include a
+// module summary. The counts for items with nested items (e.g. modules, traits,
+// impls) include all children counts.
+fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
+ // count this item
+ let item_counts = match item.stability {
+ None => Counts { unmarked: 1, .. Zero::zero() },
+ Some(ref stab) => match stab.level {
+ Deprecated => Counts { deprecated: 1, .. Zero::zero() },
+ Experimental => Counts { experimental: 1, .. Zero::zero() },
+ Unstable => Counts { unstable: 1, .. Zero::zero() },
+ Stable => Counts { stable: 1, .. Zero::zero() },
+ Frozen => Counts { frozen: 1, .. Zero::zero() },
+ Locked => Counts { locked: 1, .. Zero::zero() },
+ }
+ };
+
+ // Count this item's children, if any. Note that a trait impl is
+ // considered to have no children.
+ match item.inner {
+ // Require explicit `pub` to be visible
+ StructItem(Struct { fields: ref subitems, .. }) |
+ ImplItem(Impl { methods: ref subitems, trait_: None, .. }) => {
+ let subcounts = subitems.iter().filter(|i| visible(*i))
+ .map(summarize_item)
+ .map(|s| s.val0())
+ .sum();
+ (item_counts + subcounts, None)
+ }
+ // `pub` automatically
+ EnumItem(Enum { variants: ref subitems, .. }) => {
+ let subcounts = subitems.iter().map(summarize_item)
+ .map(|s| s.val0())
+ .sum();
+ (item_counts + subcounts, None)
+ }
+ TraitItem(Trait { methods: ref methods, .. }) => {
+ fn extract_item<'a>(meth: &'a TraitMethod) -> &'a Item {
+ match *meth {
+ Provided(ref item) | Required(ref item) => item
+ }
+ }
+ let subcounts = methods.iter().map(extract_item)
+ .map(summarize_item)
+ .map(|s| s.val0())
+ .sum();
+ (item_counts + subcounts, None)
+ }
+ ModuleItem(Module { items: ref items, .. }) => {
+ let mut counts = item_counts;
+ let mut submodules = Vec::new();
+
+ for (subcounts, submodule) in items.iter().filter(|i| visible(*i))
+ .map(summarize_item) {
+ counts = counts + subcounts;
+ submodule.map(|m| submodules.push(m));
+ }
+ submodules.sort();
+
+ (counts, Some(ModuleSummary {
+ name: item.name.as_ref().map_or("".to_string(), |n| n.clone()),
+ counts: counts,
+ submodules: submodules,
+ }))
+ }
+ // no stability information for the following items:
+ ViewItemItem(_) | PrimitiveItem(_) => (Zero::zero(), None),
+ _ => (item_counts, None)
+ }
+}
+
+/// Summarizes the stability levels in a crate.
+pub fn build(krate: &Crate) -> ModuleSummary {
+ match krate.module {
+ None => ModuleSummary {
+ name: krate.name.clone(),
+ counts: Zero::zero(),
+ submodules: Vec::new(),
+ },
+ Some(ref item) => ModuleSummary {
+ name: krate.name.clone(), .. summarize_item(item).val1().unwrap()
+ }
+ }
+}
let codemap = CodeMap::new();
- let diagnostic_handler = diagnostic::default_handler(diagnostic::Auto);
+ let diagnostic_handler = diagnostic::default_handler(diagnostic::Auto, None);
let span_diagnostic_handler =
diagnostic::mk_span_handler(diagnostic_handler, codemap);
}));
let krate = driver::phase_1_parse_input(&sess, cfg, &input);
let (krate, _) = driver::phase_2_configure_and_expand(&sess, krate,
- &from_str("rustdoc-test").unwrap())
+ "rustdoc-test")
.expect("phase_2_configure_and_expand aborted in rustdoc!");
let ctx = box(GC) core::DocContext {
};
io::util::copy(&mut p, &mut err).unwrap();
});
- let emitter = diagnostic::EmitterWriter::new(box w2);
+ let emitter = diagnostic::EmitterWriter::new(box w2, None);
// Compile the code
let codemap = CodeMap::new();
// environment to ensure that the target loads the right libraries at
// runtime. It would be a sad day if the *host* libraries were loaded as a
// mistake.
- let exe = outdir.path().join("rust_out");
- let env = {
+ let mut cmd = Command::new(outdir.path().join("rust_out"));
+ let newpath = {
let mut path = DynamicLibrary::search_path();
path.insert(0, libdir.clone());
-
- // Remove the previous dylib search path var
- let var = DynamicLibrary::envvar();
- let mut env: Vec<(String,String)> = os::env().move_iter().collect();
- match env.iter().position(|&(ref k, _)| k.as_slice() == var) {
- Some(i) => { env.remove(i); }
- None => {}
- };
-
- // Add the new dylib search path var
- let newpath = DynamicLibrary::create_path(path.as_slice());
- env.push((var.to_string(),
- str::from_utf8(newpath.as_slice()).unwrap().to_string()));
- env
+ DynamicLibrary::create_path(path.as_slice())
};
- match Command::new(exe).env(env.as_slice()).output() {
+ cmd.env(DynamicLibrary::envvar(), newpath.as_slice());
+
+ match cmd.output() {
Err(e) => fail!("couldn't run the test: {}{}", e,
if e.kind == io::PermissionDenied {
" - maybe your tempdir is mounted with noexec?"
mod imp {
use core::prelude::*;
- use alloc::owned::Box;
+ use alloc::boxed::Box;
use collections::vec::Vec;
use core::mem;
use core::slice;
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use collections::vec::Vec;
use core::atomics;
use core::mem;
use alloc::libc_heap::malloc_raw;
use collections::string::String;
+use collections::hash;
use core::kinds::marker;
use core::mem;
use core::ptr;
}
}
+impl PartialOrd for CString {
+ #[inline]
+ fn partial_cmp(&self, other: &CString) -> Option<Ordering> {
+ self.as_bytes().partial_cmp(&other.as_bytes())
+ }
+}
+
+impl Eq for CString {}
+
+impl<S: hash::Writer> hash::Hash<S> for CString {
+ #[inline]
+ fn hash(&self, state: &mut S) {
+ self.as_bytes().hash(state)
+ }
+}
+
impl CString {
/// Create a C String from a pointer.
pub unsafe fn new(buf: *const libc::c_char, owns_buffer: bool) -> CString {
Mary had a little lamb, Little lamb
Mary had a little lamb, Little lamb";
- fn bench_to_str(b: &mut Bencher, s: &str) {
+ fn bench_to_string(b: &mut Bencher, s: &str) {
b.iter(|| {
let c_str = s.to_c_str();
check(s, c_str.as_ptr());
#[bench]
fn bench_to_c_str_short(b: &mut Bencher) {
- bench_to_str(b, s_short)
+ bench_to_string(b, s_short)
}
#[bench]
fn bench_to_c_str_medium(b: &mut Bencher) {
- bench_to_str(b, s_medium)
+ bench_to_string(b, s_medium)
}
#[bench]
fn bench_to_c_str_long(b: &mut Bencher) {
- bench_to_str(b, s_long)
+ bench_to_string(b, s_long)
}
fn bench_to_c_str_unchecked(b: &mut Bencher, s: &str) {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![crate_id = "rustrt#0.11.0"]
+#![crate_name = "rustrt"]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+ html_root_url = "http://doc.rust-lang.org/master/")]
#![feature(macro_rules, phase, globs, thread_local, managed_boxes, asm)]
-#![feature(linkage, lang_items, unsafe_destructor)]
+#![feature(linkage, lang_items, unsafe_destructor, default_type_params)]
#![no_std]
#![experimental]
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use core::any::Any;
use task::{Task, BlockedTask, TaskOpts};
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use local_ptr;
use task::Task;
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use collections::vec::Vec;
use core::kinds::marker;
use core::mem;
use core::prelude::*;
use core::mem;
-use alloc::owned::Box;
+use alloc::boxed::Box;
#[cfg(windows)] // mingw-w32 doesn't like thread_local things
#[cfg(target_os = "android")] // see #10686
pub mod compiled {
use core::prelude::*;
- use alloc::owned::Box;
+ use alloc::boxed::Box;
use core::mem;
#[cfg(test)]
pub mod native {
use core::prelude::*;
- use alloc::owned::Box;
+ use alloc::boxed::Box;
use core::mem;
use core::ptr;
use tls = thread_local_storage;
//! The EventLoop and internal synchronous I/O interface.
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use collections::string::String;
use collections::vec::Vec;
use core::fmt;
/// Optional environment to specify for the program. If this is None, then
/// it will inherit the current process's environment.
- pub env: Option<&'a [(CString, CString)]>,
+ pub env: Option<&'a [(&'a CString, &'a CString)]>,
/// Optional working directory for the new process. If this is None, then
/// the current directory of the running process is inherited.
#[lang = "stack_exhausted"]
extern fn stack_exhausted() {
use core::prelude::*;
- use alloc::owned::Box;
+ use alloc::boxed::Box;
use local::Local;
use task::Task;
use core::intrinsics;
use core::prelude::*;
use alloc::arc::Arc;
-use alloc::owned::{AnyOwnExt, Box};
+use alloc::boxed::{BoxAny, Box};
use core::any::Any;
use core::atomics::{AtomicUint, SeqCst};
use core::iter::Take;
unsafe {
let imp = self.imp.take_unwrap();
let vtable = mem::transmute::<_, &raw::TraitObject>(&imp).vtable;
- match imp.wrap().move::<T>() {
+ match imp.wrap().downcast::<T>() {
Ok(t) => Some(t),
Err(t) => {
let data = mem::transmute::<_, raw::TraitObject>(t).data;
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use core::mem;
use core::uint;
use libc;
mod imp {
use core::prelude::*;
- use alloc::owned::Box;
+ use alloc::boxed::Box;
use core::cmp;
use core::mem;
use core::ptr;
mod imp {
use core::prelude::*;
- use alloc::owned::Box;
+ use alloc::boxed::Box;
use core::cmp;
use core::mem;
use core::ptr;
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use collections::string::String;
use collections::vec::Vec;
use core::any::Any;
let path = &"./tmp/mk_rm_dir".to_c_str();
let mode = S_IWUSR | S_IRUSR;
- let result = FsRequest::mkdir(l(), path, mode);
+ let result = FsRequest::mkdir(l(), path, mode as c_int);
assert!(result.is_ok());
let result = FsRequest::rmdir(l(), path);
*/
-#![crate_id = "rustuv#0.11.0"]
+#![crate_name = "rustuv"]
#![experimental]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
#![feature(macro_rules, unsafe_destructor)]
#[test]
fn error_smoke_test() {
let err: UvError = UvError(uvll::EOF);
- assert_eq!(err.to_str(), "EOF: end of file".to_string());
+ assert_eq!(err.to_string(), "EOF: end of file".to_string());
}
#[cfg(unix)]
uvll::EADDRNOTAVAIL => libc::WSAEADDRNOTAVAIL,
uvll::ECANCELED => libc::ERROR_OPERATION_ABORTED,
uvll::EADDRINUSE => libc::WSAEADDRINUSE,
+ uvll::EPERM => libc::ERROR_ACCESS_DENIED,
err => {
uvdebug!("uverr.code {}", err as int);
// FIXME: Need to map remaining uv error types
fn join_multicast(&mut self, multi: rtio::IpAddr) -> Result<(), IoError> {
let _m = self.fire_homing_missile();
status_to_io_result(unsafe {
- multi.to_str().with_c_str(|m_addr| {
+ multi.to_string().with_c_str(|m_addr| {
uvll::uv_udp_set_membership(self.handle,
m_addr, ptr::null(),
uvll::UV_JOIN_GROUP)
fn leave_multicast(&mut self, multi: rtio::IpAddr) -> Result<(), IoError> {
let _m = self.fire_homing_missile();
status_to_io_result(unsafe {
- multi.to_str().with_c_str(|m_addr| {
+ multi.to_string().with_c_str(|m_addr| {
uvll::uv_udp_set_membership(self.handle,
m_addr, ptr::null(),
uvll::UV_LEAVE_GROUP)
}
/// Converts the environment to the env array expected by libuv
-fn with_env<T>(env: Option<&[(CString, CString)]>,
+fn with_env<T>(env: Option<&[(&CString, &CString)]>,
cb: |*const *const libc::c_char| -> T) -> T {
// We can pass a char** for envp, which is a null-terminated array
// of "k=v\0" strings. Since we must create these strings locally,
pub use self::errors::{EACCES, ECONNREFUSED, ECONNRESET, EPIPE, ECONNABORTED,
ECANCELED, EBADF, ENOTCONN, ENOENT, EADDRNOTAVAIL,
- EADDRINUSE};
+ EADDRINUSE, EPERM};
pub static OK: c_int = 0;
pub static EOF: c_int = -4095;
pub static EBADF: c_int = -4083;
pub static EADDRNOTAVAIL: c_int = -4090;
pub static EADDRINUSE: c_int = -4091;
+ pub static EPERM: c_int = -4048;
}
#[cfg(not(windows))]
pub mod errors {
pub static EBADF : c_int = -libc::EBADF;
pub static EADDRNOTAVAIL : c_int = -libc::EADDRNOTAVAIL;
pub static EADDRINUSE : c_int = -libc::EADDRINUSE;
+ pub static EPERM: c_int = -libc::EPERM;
}
pub static PROCESS_SETUID: c_int = 1 << 0;
//! An example version number with all five components is
//! `0.8.1-rc.3.0+20130922.linux`.
-#![crate_id = "semver#0.11.0"]
+#![crate_name = "semver"]
#![experimental]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+ html_root_url = "http://doc.rust-lang.org/master/")]
+#![feature(default_type_params)]
use std::char;
use std::cmp;
-use std::fmt;
use std::fmt::Show;
-use std::option::{Option, Some, None};
-use std::string::String;
+use std::fmt;
+use std::hash;
/// An identifier in the pre-release or build metadata. If the identifier can
/// be parsed as a decimal value, it will be represented with `Numeric`.
-#[deriving(Clone, PartialEq)]
+#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[allow(missing_doc)]
pub enum Identifier {
Numeric(uint),
AlphaNumeric(String)
}
-impl cmp::PartialOrd for Identifier {
- #[inline]
- fn partial_cmp(&self, other: &Identifier) -> Option<Ordering> {
- match (self, other) {
- (&Numeric(a), &Numeric(ref b)) => a.partial_cmp(b),
- (&Numeric(_), _) => Some(Less),
- (&AlphaNumeric(ref a), &AlphaNumeric(ref b)) => a.partial_cmp(b),
- (&AlphaNumeric(_), _) => Some(Greater)
- }
- }
-}
-
impl fmt::Show for Identifier {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/// Represents a version number conforming to the semantic versioning scheme.
-#[deriving(Clone)]
+#[deriving(Clone, Eq)]
pub struct Version {
/// The major version, to be incremented on incompatible changes.
pub major: uint,
}
impl cmp::PartialOrd for Version {
- #[inline]
fn partial_cmp(&self, other: &Version) -> Option<Ordering> {
- match self.major.partial_cmp(&other.major) {
- Some(Equal) => {}
+ Some(self.cmp(other))
+ }
+}
+
+impl cmp::Ord for Version {
+ fn cmp(&self, other: &Version) -> Ordering {
+ match self.major.cmp(&other.major) {
+ Equal => {}
r => return r,
}
- match self.minor.partial_cmp(&other.minor) {
- Some(Equal) => {}
+ match self.minor.cmp(&other.minor) {
+ Equal => {}
r => return r,
}
- match self.patch.partial_cmp(&other.patch) {
- Some(Equal) => {}
+ match self.patch.cmp(&other.patch) {
+ Equal => {}
r => return r,
}
// but the version of ord defined for vec
// says that [] < [pre] so we alter it here
match (self.pre.len(), other.pre.len()) {
- (0, 0) => Some(Equal),
- (0, _) => Some(Greater),
- (_, 0) => Some(Less),
- (_, _) => self.pre.partial_cmp(&other.pre)
+ (0, 0) => Equal,
+ (0, _) => Greater,
+ (_, 0) => Less,
+ (_, _) => self.pre.cmp(&other.pre)
}
}
}
+impl<S: hash::Writer> hash::Hash<S> for Version {
+ fn hash(&self, into: &mut S) {
+ self.major.hash(into);
+ self.minor.hash(into);
+ self.patch.hash(into);
+ self.pre.hash(into);
+ }
+}
+
fn take_nonempty_prefix<T:Iterator<char>>(rdr: &mut T, pred: |char| -> bool)
-> (String, Option<char>) {
let mut buf = String::new();
let v = parse_iter(&mut s.chars());
match v {
Some(v) => {
- if v.to_str().equiv(&s) {
+ if v.to_string().equiv(&s) {
Some(v)
} else {
None
}
#[test]
-fn test_to_str() {
- assert_eq!(parse("1.2.3").unwrap().to_str(), "1.2.3".to_string());
- assert_eq!(parse("1.2.3-alpha1").unwrap().to_str(), "1.2.3-alpha1".to_string());
- assert_eq!(parse("1.2.3+build.42").unwrap().to_str(), "1.2.3+build.42".to_string());
- assert_eq!(parse("1.2.3-alpha1+42").unwrap().to_str(), "1.2.3-alpha1+42".to_string());
+fn test_to_string() {
+ assert_eq!(parse("1.2.3").unwrap().to_string(), "1.2.3".to_string());
+ assert_eq!(parse("1.2.3-alpha1").unwrap().to_string(), "1.2.3-alpha1".to_string());
+ assert_eq!(parse("1.2.3+build.42").unwrap().to_string(), "1.2.3+build.42".to_string());
+ assert_eq!(parse("1.2.3-alpha1+42").unwrap().to_string(), "1.2.3-alpha1+42".to_string());
}
#[test]
// Serialize using `ToJson`
let test2 = TestStruct1 {data_int: 1, data_str:"toto".to_string(), data_vector:vec![2,3,4,5]};
let tjson: json::Json = test2.to_json();
- let json_str: String = tjson.to_str();
+ let json_str: String = tjson.to_string();
// Deserialize like before
let decoded: TestStruct1 = json::decode(json_str.as_slice()).unwrap();
pub type EncodeResult = io::IoResult<()>;
pub type DecodeResult<T> = Result<T, DecoderError>;
-fn escape_str(s: &str) -> String {
- let mut escaped = String::from_str("\"");
- for c in s.chars() {
- match c {
- '"' => escaped.push_str("\\\""),
- '\\' => escaped.push_str("\\\\"),
- '\x08' => escaped.push_str("\\b"),
- '\x0c' => escaped.push_str("\\f"),
- '\n' => escaped.push_str("\\n"),
- '\r' => escaped.push_str("\\r"),
- '\t' => escaped.push_str("\\t"),
- _ => escaped.push_char(c),
+pub fn escape_bytes(wr: &mut io::Writer, bytes: &[u8]) -> Result<(), io::IoError> {
+ try!(wr.write_str("\""));
+
+ let mut start = 0;
+
+ for (i, byte) in bytes.iter().enumerate() {
+ let escaped = match *byte {
+ b'"' => "\\\"",
+ b'\\' => "\\\\",
+ b'\x08' => "\\b",
+ b'\x0c' => "\\f",
+ b'\n' => "\\n",
+ b'\r' => "\\r",
+ b'\t' => "\\t",
+ _ => { continue; }
+ };
+
+ if start < i {
+ try!(wr.write(bytes.slice(start, i)));
}
- };
- escaped.push_char('"');
- escaped
+
+ try!(wr.write_str(escaped));
+
+ start = i + 1;
+ }
+
+ if start != bytes.len() {
+ try!(wr.write(bytes.slice_from(start)));
+ }
+
+ wr.write_str("\"")
+}
+
+fn escape_str(writer: &mut io::Writer, v: &str) -> Result<(), io::IoError> {
+ escape_bytes(writer, v.as_bytes())
+}
+
+fn escape_char(writer: &mut io::Writer, v: char) -> Result<(), io::IoError> {
+ let mut buf = [0, .. 4];
+ v.encode_utf8(buf);
+ escape_bytes(writer, buf)
+}
+
+fn spaces(wr: &mut io::Writer, mut n: uint) -> Result<(), io::IoError> {
+ static len: uint = 16;
+ static buf: [u8, ..len] = [b' ', ..len];
+
+ while n >= len {
+ try!(wr.write(buf));
+ n -= len;
+ }
+
+ if n > 0 {
+ wr.write(buf.slice_to(n))
+ } else {
+ Ok(())
+ }
}
fn fmt_number_or_null(v: f64) -> String {
}
}
-fn spaces(n: uint) -> String {
- String::from_char(n, ' ')
-}
-
/// A structure for implementing serialization to JSON.
pub struct Encoder<'a> {
writer: &'a mut io::Writer,
fn emit_f32(&mut self, v: f32) -> EncodeResult { self.emit_f64(v as f64) }
fn emit_char(&mut self, v: char) -> EncodeResult {
- self.emit_str(str::from_char(v).as_slice())
+ escape_char(self.writer, v)
}
fn emit_str(&mut self, v: &str) -> EncodeResult {
- write!(self.writer, "{}", escape_str(v))
+ escape_str(self.writer, v)
}
fn emit_enum(&mut self, _name: &str, f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
// Bunny => "Bunny"
// Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]}
if cnt == 0 {
- write!(self.writer, "{}", escape_str(name))
+ escape_str(self.writer, name)
} else {
try!(write!(self.writer, "{{\"variant\":"));
- try!(write!(self.writer, "{}", escape_str(name)));
+ try!(escape_str(self.writer, name));
try!(write!(self.writer, ",\"fields\":["));
try!(f(self));
write!(self.writer, "]}}")
idx: uint,
f: |&mut Encoder<'a>| -> EncodeResult) -> EncodeResult {
if idx != 0 { try!(write!(self.writer, ",")); }
- try!(write!(self.writer, "{}:", escape_str(name)));
+ try!(escape_str(self.writer, name));
+ try!(write!(self.writer, ":"));
f(self)
}
}
fn emit_char(&mut self, v: char) -> EncodeResult {
- self.emit_str(str::from_char(v).as_slice())
+ escape_char(self.writer, v)
}
fn emit_str(&mut self, v: &str) -> EncodeResult {
- write!(self.writer, "{}", escape_str(v))
+ escape_str(self.writer, v)
}
fn emit_enum(&mut self,
cnt: uint,
f: |&mut PrettyEncoder<'a>| -> EncodeResult) -> EncodeResult {
if cnt == 0 {
- write!(self.writer, "{}", escape_str(name))
+ escape_str(self.writer, name)
} else {
self.indent += 2;
- try!(write!(self.writer, "[\n{}{},\n", spaces(self.indent),
- escape_str(name)));
+ try!(write!(self.writer, "[\n"));
+ try!(spaces(self.writer, self.indent));
+ try!(escape_str(self.writer, name));
+ try!(write!(self.writer, ",\n"));
try!(f(self));
self.indent -= 2;
- write!(self.writer, "\n{}]", spaces(self.indent))
+ try!(write!(self.writer, "\n"));
+ try!(spaces(self.writer, self.indent));
+ write!(self.writer, "]")
}
}
if idx != 0 {
try!(write!(self.writer, ",\n"));
}
- try!(write!(self.writer, "{}", spaces(self.indent)));
+ try!(spaces(self.writer, self.indent));
f(self)
}
self.indent += 2;
try!(f(self));
self.indent -= 2;
- write!(self.writer, "\n{}}}", spaces(self.indent))
+ try!(write!(self.writer, "\n"));
+ try!(spaces(self.writer, self.indent));
+ write!(self.writer, "}}")
}
}
} else {
try!(write!(self.writer, ",\n"));
}
- try!(write!(self.writer, "{}{}: ", spaces(self.indent), escape_str(name)));
+ try!(spaces(self.writer, self.indent));
+ try!(escape_str(self.writer, name));
+ try!(write!(self.writer, ": "));
f(self)
}
self.indent += 2;
try!(f(self));
self.indent -= 2;
- write!(self.writer, "\n{}]", spaces(self.indent))
+ try!(write!(self.writer, "\n"));
+ try!(spaces(self.writer, self.indent));
+ write!(self.writer, "]")
}
}
} else {
try!(write!(self.writer, ",\n"));
}
- try!(write!(self.writer, "{}", spaces(self.indent)));
+ try!(spaces(self.writer, self.indent));
f(self)
}
self.indent += 2;
try!(f(self));
self.indent -= 2;
- write!(self.writer, "\n{}}}", spaces(self.indent))
+ try!(write!(self.writer, "\n"));
+ try!(spaces(self.writer, self.indent));
+ write!(self.writer, "}}")
}
}
} else {
try!(write!(self.writer, ",\n"));
}
- try!(write!(self.writer, "{}", spaces(self.indent)));
+ try!(spaces(self.writer, self.indent));
// ref #12967, make sure to wrap a key in double quotes,
// in the event that its of a type that omits them (eg numbers)
let mut buf = MemWriter::new();
/// Provides access to the current position in the logical structure of the
/// JSON stream.
pub fn stack<'l>(&'l self) -> &'l Stack {
- return &'l self.stack;
+ return &self.stack;
}
fn eof(&self) -> bool { self.ch.is_none() }
#[test]
fn test_write_null() {
- assert_eq!(Null.to_str().into_string(), "null".to_string());
+ assert_eq!(Null.to_string().into_string(), "null".to_string());
assert_eq!(Null.to_pretty_str().into_string(), "null".to_string());
}
#[test]
fn test_write_number() {
- assert_eq!(Number(3.0).to_str().into_string(), "3".to_string());
+ assert_eq!(Number(3.0).to_string().into_string(), "3".to_string());
assert_eq!(Number(3.0).to_pretty_str().into_string(), "3".to_string());
- assert_eq!(Number(3.1).to_str().into_string(), "3.1".to_string());
+ assert_eq!(Number(3.1).to_string().into_string(), "3.1".to_string());
assert_eq!(Number(3.1).to_pretty_str().into_string(), "3.1".to_string());
- assert_eq!(Number(-1.5).to_str().into_string(), "-1.5".to_string());
+ assert_eq!(Number(-1.5).to_string().into_string(), "-1.5".to_string());
assert_eq!(Number(-1.5).to_pretty_str().into_string(), "-1.5".to_string());
- assert_eq!(Number(0.5).to_str().into_string(), "0.5".to_string());
+ assert_eq!(Number(0.5).to_string().into_string(), "0.5".to_string());
assert_eq!(Number(0.5).to_pretty_str().into_string(), "0.5".to_string());
- assert_eq!(Number(f64::NAN).to_str().into_string(), "null".to_string());
+ assert_eq!(Number(f64::NAN).to_string().into_string(), "null".to_string());
assert_eq!(Number(f64::NAN).to_pretty_str().into_string(), "null".to_string());
- assert_eq!(Number(f64::INFINITY).to_str().into_string(), "null".to_string());
+ assert_eq!(Number(f64::INFINITY).to_string().into_string(), "null".to_string());
assert_eq!(Number(f64::INFINITY).to_pretty_str().into_string(), "null".to_string());
- assert_eq!(Number(f64::NEG_INFINITY).to_str().into_string(), "null".to_string());
+ assert_eq!(Number(f64::NEG_INFINITY).to_string().into_string(), "null".to_string());
assert_eq!(Number(f64::NEG_INFINITY).to_pretty_str().into_string(), "null".to_string());
}
#[test]
fn test_write_str() {
- assert_eq!(String("".to_string()).to_str().into_string(), "\"\"".to_string());
+ assert_eq!(String("".to_string()).to_string().into_string(), "\"\"".to_string());
assert_eq!(String("".to_string()).to_pretty_str().into_string(), "\"\"".to_string());
- assert_eq!(String("foo".to_string()).to_str().into_string(), "\"foo\"".to_string());
+ assert_eq!(String("foo".to_string()).to_string().into_string(), "\"foo\"".to_string());
assert_eq!(String("foo".to_string()).to_pretty_str().into_string(), "\"foo\"".to_string());
}
#[test]
fn test_write_bool() {
- assert_eq!(Boolean(true).to_str().into_string(), "true".to_string());
+ assert_eq!(Boolean(true).to_string().into_string(), "true".to_string());
assert_eq!(Boolean(true).to_pretty_str().into_string(), "true".to_string());
- assert_eq!(Boolean(false).to_str().into_string(), "false".to_string());
+ assert_eq!(Boolean(false).to_string().into_string(), "false".to_string());
assert_eq!(Boolean(false).to_pretty_str().into_string(), "false".to_string());
}
#[test]
fn test_write_list() {
- assert_eq!(List(vec![]).to_str().into_string(), "[]".to_string());
+ assert_eq!(List(vec![]).to_string().into_string(), "[]".to_string());
assert_eq!(List(vec![]).to_pretty_str().into_string(), "[]".to_string());
- assert_eq!(List(vec![Boolean(true)]).to_str().into_string(), "[true]".to_string());
+ assert_eq!(List(vec![Boolean(true)]).to_string().into_string(), "[true]".to_string());
assert_eq!(
List(vec![Boolean(true)]).to_pretty_str().into_string(),
"\
Null,
List(vec![String("foo\nbar".to_string()), Number(3.5)])]);
- assert_eq!(long_test_list.to_str().into_string(),
+ assert_eq!(long_test_list.to_string().into_string(),
"[false,null,[\"foo\\nbar\",3.5]]".to_string());
assert_eq!(
long_test_list.to_pretty_str().into_string(),
#[test]
fn test_write_object() {
- assert_eq!(mk_object([]).to_str().into_string(), "{}".to_string());
+ assert_eq!(mk_object([]).to_string().into_string(), "{}".to_string());
assert_eq!(mk_object([]).to_pretty_str().into_string(), "{}".to_string());
assert_eq!(
mk_object([
("a".to_string(), Boolean(true))
- ]).to_str().into_string(),
+ ]).to_string().into_string(),
"{\"a\":true}".to_string()
);
assert_eq!(
]);
assert_eq!(
- complex_obj.to_str().into_string(),
+ complex_obj.to_string().into_string(),
"{\
\"b\":[\
{\"c\":\"\\f\\r\"},\
// We can't compare the strings directly because the object fields be
// printed in a different order.
- assert_eq!(a.clone(), from_str(a.to_str().as_slice()).unwrap());
+ assert_eq!(a.clone(), from_str(a.to_string().as_slice()).unwrap());
assert_eq!(a.clone(),
from_str(a.to_pretty_str().as_slice()).unwrap());
}
Core encoding and decoding interfaces.
*/
-#![crate_id = "serialize#0.11.0"]
+#![crate_name = "serialize"]
#![experimental]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
#![feature(macro_rules, managed_boxes, default_type_params, phase)]
use std::path;
use std::rc::Rc;
use std::gc::{Gc, GC};
+use std::cell::{Cell, RefCell};
pub trait Encoder<E> {
// Primitive types:
}
}
+impl<E, S: Encoder<E>, T: Encodable<S, E> + Copy> Encodable<S, E> for Cell<T> {
+ fn encode(&self, s: &mut S) -> Result<(), E> {
+ self.get().encode(s)
+ }
+}
+
+impl<E, D: Decoder<E>, T: Decodable<D, E> + Copy> Decodable<D, E> for Cell<T> {
+ fn decode(d: &mut D) -> Result<Cell<T>, E> {
+ Ok(Cell::new(try!(Decodable::decode(d))))
+ }
+}
+
+// FIXME: #15036
+// Should use `try_borrow`, returning a
+// `encoder.error("attempting to Encode borrowed RefCell")`
+// from `encode` when `try_borrow` returns `None`.
+
+impl<E, S: Encoder<E>, T: Encodable<S, E>> Encodable<S, E> for RefCell<T> {
+ fn encode(&self, s: &mut S) -> Result<(), E> {
+ self.borrow().encode(s)
+ }
+}
+
+impl<E, D: Decoder<E>, T: Decodable<D, E>> Decodable<D, E> for RefCell<T> {
+ fn decode(d: &mut D) -> Result<RefCell<T>, E> {
+ Ok(RefCell::new(try!(Decodable::decode(d))))
+ }
+}
+
// ___________________________________________________________________________
// Helper routines
//
impl IntoStr for Vec<Ascii> {
#[inline]
- fn into_str(self) -> String {
+ fn into_string(self) -> String {
unsafe {
let s: &str = mem::transmute(self.as_slice());
- s.to_string()
+ String::from_str(s)
}
}
}
*b = map[*b as uint];
}
- str::from_utf8(bytes.as_slice()).unwrap().to_string()
+ String::from_str(str::from_utf8(bytes.as_slice()).unwrap())
}
#[inline]
unsafe fn str_copy_map_bytes(string: &str, map: &'static [u8]) -> String {
- let mut s = string.to_string();
+ let mut s = String::from_str(string);
for b in s.as_mut_bytes().mut_iter() {
*b = map[*b as uint];
}
assert_eq!(v.as_slice().to_ascii(), v2ascii!([40, 32, 59]));
assert_eq!("( ;".to_string().as_slice().to_ascii(), v2ascii!([40, 32, 59]));
- assert_eq!("abCDef&?#".to_ascii().to_lower().into_str(), "abcdef&?#".to_string());
- assert_eq!("abCDef&?#".to_ascii().to_upper().into_str(), "ABCDEF&?#".to_string());
+ assert_eq!("abCDef&?#".to_ascii().to_lower().into_string(), "abcdef&?#".to_string());
+ assert_eq!("abCDef&?#".to_ascii().to_upper().into_string(), "ABCDEF&?#".to_string());
- assert_eq!("".to_ascii().to_lower().into_str(), "".to_string());
- assert_eq!("YMCA".to_ascii().to_lower().into_str(), "ymca".to_string());
- assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().into_str(), "ABCDEFXYZ:.;".to_string());
+ assert_eq!("".to_ascii().to_lower().into_string(), "".to_string());
+ assert_eq!("YMCA".to_ascii().to_lower().into_string(), "ymca".to_string());
+ assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().into_string(), "ABCDEFXYZ:.;".to_string());
assert!("aBcDeF&?#".to_ascii().eq_ignore_case("AbCdEf&?#".to_ascii()));
#[test]
fn test_ascii_vec_ng() {
- assert_eq!("abCDef&?#".to_ascii().to_lower().into_str(), "abcdef&?#".to_string());
- assert_eq!("abCDef&?#".to_ascii().to_upper().into_str(), "ABCDEF&?#".to_string());
- assert_eq!("".to_ascii().to_lower().into_str(), "".to_string());
- assert_eq!("YMCA".to_ascii().to_lower().into_str(), "ymca".to_string());
- assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().into_str(), "ABCDEFXYZ:.;".to_string());
+ assert_eq!("abCDef&?#".to_ascii().to_lower().into_string(), "abcdef&?#".to_string());
+ assert_eq!("abCDef&?#".to_ascii().to_upper().into_string(), "ABCDEF&?#".to_string());
+ assert_eq!("".to_ascii().to_lower().into_string(), "".to_string());
+ assert_eq!("YMCA".to_ascii().to_lower().into_string(), "ymca".to_string());
+ assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().into_string(), "ABCDEFXYZ:.;".to_string());
}
#[test]
}
#[test]
- fn test_ascii_into_str() {
- assert_eq!(vec2ascii![40, 32, 59].into_str(), "( ;".to_string());
- assert_eq!(vec2ascii!(40, 32, 59).into_str(), "( ;".to_string());
+ fn test_ascii_into_string() {
+ assert_eq!(vec2ascii![40, 32, 59].into_string(), "( ;".to_string());
+ assert_eq!(vec2ascii!(40, 32, 59).into_string(), "( ;".to_string());
}
#[test]
}
#[test]
- fn test_to_str() {
- let s = Ascii{ chr: 't' as u8 }.to_str();
+ fn test_to_string() {
+ let s = Ascii{ chr: 't' as u8 }.to_string();
assert_eq!(s, "t".to_string());
}
unsafe {
debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
- (&'a *self.keys.offset(idx),
- &'a *self.vals.offset(idx))
+ (&*self.keys.offset(idx), &*self.vals.offset(idx))
}
}
unsafe {
debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
- (&'a *self.keys.offset(idx),
- &'a mut *self.vals.offset(idx))
+ (&*self.keys.offset(idx), &mut *self.vals.offset(idx))
}
}
unsafe {
debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
(transmute(self.hashes.offset(idx)),
- &'a mut *self.keys.offset(idx),
- &'a mut *self.vals.offset(idx))
+ &mut *self.keys.offset(idx), &mut *self.vals.offset(idx))
}
}
use mem;
use ops::Drop;
use option::{Some, None, Option};
-use owned::Box;
+use boxed::Box;
use ptr;
use result::{Ok, Err};
}
#[test]
- fn test_to_str() {
+ fn test_to_string() {
let mut cache: LruCache<int, int> = LruCache::new(3);
cache.put(1, 10);
cache.put(2, 20);
cache.put(3, 30);
- assert_eq!(cache.to_str(), "{3: 30, 2: 20, 1: 10}".to_string());
+ assert_eq!(cache.to_string(), "{3: 30, 2: 20, 1: 10}".to_string());
cache.put(2, 22);
- assert_eq!(cache.to_str(), "{2: 22, 3: 30, 1: 10}".to_string());
+ assert_eq!(cache.to_string(), "{2: 22, 3: 30, 1: 10}".to_string());
cache.put(6, 60);
- assert_eq!(cache.to_str(), "{6: 60, 2: 22, 3: 30}".to_string());
+ assert_eq!(cache.to_string(), "{6: 60, 2: 22, 3: 30}".to_string());
cache.get(&3);
- assert_eq!(cache.to_str(), "{3: 30, 6: 60, 2: 22}".to_string());
+ assert_eq!(cache.to_string(), "{3: 30, 6: 60, 2: 22}".to_string());
cache.change_capacity(2);
- assert_eq!(cache.to_str(), "{3: 30, 6: 60}".to_string());
+ assert_eq!(cache.to_string(), "{3: 30, 6: 60}".to_string());
}
#[test]
cache.clear();
assert!(cache.get(&1).is_none());
assert!(cache.get(&2).is_none());
- assert_eq!(cache.to_str(), "{}".to_string());
+ assert_eq!(cache.to_string(), "{}".to_string());
}
}
#[cfg(target_os = "ios")]
#[cfg(target_os = "freebsd")]
pub mod dl {
- use prelude::*;
use c_str::{CString, ToCStr};
use libc;
use ptr;
use result::*;
- use str::StrAllocating;
use string::String;
pub unsafe fn open_external<T: ToCStr>(filename: T) -> *mut u8 {
let ret = if ptr::null() == last_error {
Ok(result)
} else {
- Err(CString::new(last_error, false).as_str()
- .unwrap()
- .to_string())
+ Err(String::from_str(CString::new(last_error, false).as_str()
+ .unwrap()))
};
ret
#![experimental]
-use alloc::owned::Box;
+use alloc::boxed::Box;
use any::{Any, AnyRefExt};
use fmt;
use io::{Writer, IoResult};
use option::{Option, Some, None};
use string::String;
-use str::StrAllocating;
/// A trait to abstract the idea of creating a new instance of a type from a
/// string.
impl FromStr for String {
#[inline]
fn from_str(s: &str) -> Option<String> {
- Some(s.to_string())
+ Some(String::from_str(s))
}
}
* ```
*/
+#![experimental]
+
pub use core_collections::hash::{Hash, Hasher, Writer, hash, sip};
use default::Default;
use prelude::*;
use self::test::Bencher;
+ // why is this a macro? wouldn't an inlined function work just as well?
macro_rules! u64_from_be_bytes_bench_impl(
- ($size:expr, $stride:expr, $start_index:expr) =>
+ ($b:expr, $size:expr, $stride:expr, $start_index:expr) =>
({
use super::u64_from_be_bytes;
let data = Vec::from_fn($stride*100+$start_index, |i| i as u8);
let mut sum = 0u64;
- b.iter(|| {
+ $b.iter(|| {
let mut i = $start_index;
while i < data.len() {
sum += u64_from_be_bytes(data.as_slice(), i, $size);
#[bench]
fn u64_from_be_bytes_4_aligned(b: &mut Bencher) {
- u64_from_be_bytes_bench_impl!(4, 4, 0);
+ u64_from_be_bytes_bench_impl!(b, 4, 4, 0);
}
#[bench]
fn u64_from_be_bytes_4_unaligned(b: &mut Bencher) {
- u64_from_be_bytes_bench_impl!(4, 4, 1);
+ u64_from_be_bytes_bench_impl!(b, 4, 4, 1);
}
#[bench]
fn u64_from_be_bytes_7_aligned(b: &mut Bencher) {
- u64_from_be_bytes_bench_impl!(7, 8, 0);
+ u64_from_be_bytes_bench_impl!(b, 7, 8, 0);
}
#[bench]
fn u64_from_be_bytes_7_unaligned(b: &mut Bencher) {
- u64_from_be_bytes_bench_impl!(7, 8, 1);
+ u64_from_be_bytes_bench_impl!(b, 7, 8, 1);
}
#[bench]
fn u64_from_be_bytes_8_aligned(b: &mut Bencher) {
- u64_from_be_bytes_bench_impl!(8, 8, 0);
+ u64_from_be_bytes_bench_impl!(b, 8, 8, 0);
}
#[bench]
fn u64_from_be_bytes_8_unaligned(b: &mut Bencher) {
- u64_from_be_bytes_bench_impl!(8, 8, 1);
+ u64_from_be_bytes_bench_impl!(b, 8, 8, 1);
}
}
use kinds::Send;
use libc;
use option::{Some, None, Option};
-use owned::Box;
+use boxed::Box;
use path::{Path, GenericPath};
use path;
use result::{Err, Ok};
/// user lacks permissions to remove the file, or if some other filesystem-level
/// error occurs.
pub fn unlink(path: &Path) -> IoResult<()> {
- let err = LocalIo::maybe_raise(|io| {
- io.fs_unlink(&path.to_c_str())
- }).map_err(IoError::from_rtio_error);
- err.update_err("couldn't unlink path",
- |e| format!("{}; path={}", e, path.display()))
+ return match do_unlink(path) {
+ Ok(()) => Ok(()),
+ Err(e) => {
+ // On unix, a readonly file can be successfully removed. On windows,
+ // however, it cannot. To keep the two platforms in line with
+ // respect to their behavior, catch this case on windows, attempt to
+ // change it to read-write, and then remove the file.
+ if cfg!(windows) && e.kind == io::PermissionDenied {
+ let stat = match stat(path) {
+ Ok(stat) => stat,
+ Err(..) => return Err(e),
+ };
+ if stat.perm.intersects(io::UserWrite) { return Err(e) }
+
+ match chmod(path, stat.perm | io::UserWrite) {
+ Ok(()) => do_unlink(path),
+ Err(..) => {
+ // Try to put it back as we found it
+ let _ = chmod(path, stat.perm);
+ Err(e)
+ }
+ }
+ } else {
+ Err(e)
+ }
+ }
+ };
+
+ fn do_unlink(path: &Path) -> IoResult<()> {
+ let err = LocalIo::maybe_raise(|io| {
+ io.fs_unlink(&path.to_c_str())
+ }).map_err(IoError::from_rtio_error);
+ err.update_err("couldn't unlink path",
+ |e| format!("{}; path={}", e, path.display()))
+ }
}
/// Given a path, query the file system to get information about a file,
}
fn from_rtio(s: rtio::FileStat) -> FileStat {
+ #[cfg(windows)]
+ type Mode = libc::c_int;
+ #[cfg(unix)]
+ type Mode = libc::mode_t;
+
let rtio::FileStat {
size, kind, perm, created, modified,
accessed, device, inode, rdev,
FileStat {
size: size,
- kind: match (kind as libc::c_int) & libc::S_IFMT {
+ kind: match (kind as Mode) & libc::S_IFMT {
libc::S_IFREG => io::TypeFile,
libc::S_IFDIR => io::TypeDirectory,
libc::S_IFIFO => io::TypeNamedPipe,
macro_rules! error( ($e:expr, $s:expr) => (
match $e {
Ok(val) => fail!("Should have been an error, was {:?}", val),
- Err(ref err) => assert!(err.to_str().as_slice().contains($s.as_slice()),
+ Err(ref err) => assert!(err.to_string().as_slice().contains($s.as_slice()),
format!("`{}` did not contain `{}`", err, $s))
}
) )
for n in range(0i,3) {
let f = dir.join(format!("{}.txt", n));
let mut w = check!(File::create(&f));
- let msg_str = format!("{}{}", prefix, n.to_str());
+ let msg_str = format!("{}{}", prefix, n.to_string());
let msg = msg_str.as_slice().as_bytes();
check!(w.write(msg));
}
let actual = check!(File::open(&tmpdir.join("test")).read_to_end());
assert!(actual.as_slice() == bytes);
})
+
+ iotest!(fn unlink_readonly() {
+ let tmpdir = tmpdir();
+ let path = tmpdir.join("file");
+ check!(File::create(&path));
+ check!(chmod(&path, io::UserRead));
+ check!(unlink(&path));
+ })
}
#[inline]
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
// return an error if the entire write does not fit in the buffer
- let max_size = self.buf.len();
- if self.pos >= max_size || (self.pos + buf.len()) > max_size {
+ let cap = if self.pos >= self.buf.len() { 0 } else { self.buf.len() - self.pos };
+ if buf.len() > cap {
return Err(IoError {
kind: io::OtherIoError,
desc: "Trying to write past end of buffer",
writer.write([1, 2, 3]).unwrap();
writer.write([4, 5, 6, 7]).unwrap();
assert_eq!(writer.tell(), Ok(8));
+ writer.write([]).unwrap();
+ assert_eq!(writer.tell(), Ok(8));
}
assert_eq!(buf.as_slice(), &[0, 1, 2, 3, 4, 5, 6, 7]);
}
writer.write_line("testing").unwrap();
writer.write_str("testing").unwrap();
let mut r = BufReader::new(writer.get_ref());
- assert_eq!(r.read_to_str().unwrap(), "testingtesting\ntesting".to_string());
+ assert_eq!(r.read_to_string().unwrap(), "testingtesting\ntesting".to_string());
}
#[test]
writer.write_char('\n').unwrap();
writer.write_char('ệ').unwrap();
let mut r = BufReader::new(writer.get_ref());
- assert_eq!(r.read_to_str().unwrap(), "a\nệ".to_string());
+ assert_eq!(r.read_to_string().unwrap(), "a\nệ".to_string());
}
#[test]
fn test_read_whole_string_bad() {
let buf = [0xff];
let mut r = BufReader::new(buf);
- match r.read_to_str() {
+ match r.read_to_string() {
Ok(..) => fail!(),
Err(..) => {}
}
assert_eq!(buf.as_slice(), &[7, 8, 6]);
}
- #[bench]
- fn bench_mem_writer(b: &mut Bencher) {
+ fn do_bench_mem_writer(b: &mut Bencher, times: uint, len: uint) {
+ let src: Vec<u8> = Vec::from_elem(len, 5);
+
b.iter(|| {
let mut wr = MemWriter::new();
- for _i in range(0u, 10) {
- wr.write([5, .. 10]).unwrap();
+ for _ in range(0, times) {
+ wr.write(src.as_slice()).unwrap();
}
- assert_eq!(wr.unwrap().as_slice(), [5, .. 100].as_slice());
+
+ let v = wr.unwrap();
+ assert_eq!(v.len(), times * len);
+ assert!(v.iter().all(|x| *x == 5));
});
}
+ #[bench]
+ fn bench_mem_writer_001_0000(b: &mut Bencher) {
+ do_bench_mem_writer(b, 1, 0)
+ }
+
+ #[bench]
+ fn bench_mem_writer_001_0010(b: &mut Bencher) {
+ do_bench_mem_writer(b, 1, 10)
+ }
+
+ #[bench]
+ fn bench_mem_writer_001_0100(b: &mut Bencher) {
+ do_bench_mem_writer(b, 1, 100)
+ }
+
+ #[bench]
+ fn bench_mem_writer_001_1000(b: &mut Bencher) {
+ do_bench_mem_writer(b, 1, 1000)
+ }
+
+ #[bench]
+ fn bench_mem_writer_100_0000(b: &mut Bencher) {
+ do_bench_mem_writer(b, 100, 0)
+ }
+
+ #[bench]
+ fn bench_mem_writer_100_0010(b: &mut Bencher) {
+ do_bench_mem_writer(b, 100, 10)
+ }
+
+ #[bench]
+ fn bench_mem_writer_100_0100(b: &mut Bencher) {
+ do_bench_mem_writer(b, 100, 100)
+ }
+
+ #[bench]
+ fn bench_mem_writer_100_1000(b: &mut Bencher) {
+ do_bench_mem_writer(b, 100, 1000)
+ }
+
#[bench]
fn bench_mem_reader(b: &mut Bencher) {
b.iter(|| {
use ops::{BitOr, BitAnd, Sub, Not};
use option::{Option, Some, None};
use os;
-use owned::Box;
+use boxed::Box;
use result::{Ok, Err, Result};
use rt::rtio;
use slice::{Vector, MutableVector, ImmutableVector};
-use str::{Str, StrSlice, StrAllocating};
+use str::{Str, StrSlice};
use str;
use string::String;
use uint;
+use unicode::UnicodeChar;
use vec::Vec;
// Reexports
/// # FIXME
///
/// Is something like this sufficient? It's kind of archaic
-#[deriving(PartialEq, Clone)]
+#[deriving(PartialEq, Eq, Clone)]
pub struct IoError {
/// An enumeration which can be matched against for determining the flavor
/// of error.
}
/// A list specifying general categories of I/O error.
-#[deriving(PartialEq, Clone, Show)]
+#[deriving(PartialEq, Eq, Clone, Show)]
pub enum IoErrorKind {
/// Any I/O error not part of this list.
OtherIoError,
fn read_at_least(&mut self, min: uint, buf: &mut [u8]) -> IoResult<uint> {
if min > buf.len() {
return Err(IoError {
- detail: Some("the buffer is too short".to_string()),
+ detail: Some(String::from_str("the buffer is too short")),
..standard_error(InvalidInput)
});
}
fn push_at_least(&mut self, min: uint, len: uint, buf: &mut Vec<u8>) -> IoResult<uint> {
if min > len {
return Err(IoError {
- detail: Some("the buffer is too short".to_string()),
+ detail: Some(String::from_str("the buffer is too short")),
..standard_error(InvalidInput)
});
}
/// This function returns all of the same errors as `read_to_end` with an
/// additional error if the reader's contents are not a valid sequence of
/// UTF-8 bytes.
- fn read_to_str(&mut self) -> IoResult<String> {
+ fn read_to_string(&mut self) -> IoResult<String> {
self.read_to_end().and_then(|s| {
match str::from_utf8(s.as_slice()) {
- Some(s) => Ok(s.to_string()),
+ Some(s) => Ok(String::from_str(s)),
None => Err(standard_error(InvalidInput)),
}
})
fn read_line(&mut self) -> IoResult<String> {
self.read_until('\n' as u8).and_then(|line|
match str::from_utf8(line.as_slice()) {
- Some(s) => Ok(s.to_string()),
+ Some(s) => Ok(String::from_str(s)),
None => Err(standard_error(InvalidInput)),
}
)
}
#[test]
- fn ipv6_addr_to_str() {
+ fn ipv6_addr_to_string() {
let a1 = Ipv6Addr(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x280);
- assert!(a1.to_str() == "::ffff:192.0.2.128".to_string() ||
- a1.to_str() == "::FFFF:192.0.2.128".to_string());
- assert_eq!(Ipv6Addr(8, 9, 10, 11, 12, 13, 14, 15).to_str(), "8:9:a:b:c:d:e:f".to_string());
+ assert!(a1.to_string() == "::ffff:192.0.2.128".to_string() ||
+ a1.to_string() == "::FFFF:192.0.2.128".to_string());
+ assert_eq!(Ipv6Addr(8, 9, 10, 11, 12, 13, 14, 15).to_string(),
+ "8:9:a:b:c:d:e:f".to_string());
}
}
use from_str::FromStr;
use kinds::Send;
use option::{None, Some, Option};
-use owned::Box;
+use boxed::Box;
use rt::rtio::{IoFactory, LocalIo, RtioSocket, RtioTcpListener};
use rt::rtio::{RtioTcpAcceptor, RtioTcpStream};
use rt::rtio;
iotest!(fn listen_ip4_localhost() {
let socket_addr = next_test_ip4();
- let ip_str = socket_addr.ip.to_str();
+ let ip_str = socket_addr.ip.to_string();
let port = socket_addr.port;
let listener = TcpListener::bind(ip_str.as_slice(), port);
let mut acceptor = listener.listen();
iotest!(fn connect_localhost() {
let addr = next_test_ip4();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
iotest!(fn connect_ip4_loopback() {
let addr = next_test_ip4();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
iotest!(fn connect_ip6_loopback() {
let addr = next_test_ip6();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
iotest!(fn smoke_test_ip4() {
let addr = next_test_ip4();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
iotest!(fn smoke_test_ip6() {
let addr = next_test_ip6();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
iotest!(fn read_eof_ip4() {
let addr = next_test_ip4();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
iotest!(fn read_eof_ip6() {
let addr = next_test_ip6();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
iotest!(fn read_eof_twice_ip4() {
let addr = next_test_ip4();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
iotest!(fn read_eof_twice_ip6() {
let addr = next_test_ip6();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
iotest!(fn write_close_ip4() {
let addr = next_test_ip4();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
iotest!(fn write_close_ip6() {
let addr = next_test_ip6();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
iotest!(fn multiple_connect_serial_ip4() {
let addr = next_test_ip4();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let max = 10u;
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
iotest!(fn multiple_connect_serial_ip6() {
let addr = next_test_ip6();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let max = 10u;
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
iotest!(fn multiple_connect_interleaved_greedy_schedule_ip4() {
let addr = next_test_ip4();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
static MAX: int = 10;
let acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
connect(0, addr);
fn connect(i: int, addr: SocketAddr) {
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
if i == MAX { return }
iotest!(fn multiple_connect_interleaved_greedy_schedule_ip6() {
let addr = next_test_ip6();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
static MAX: int = 10;
let acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
connect(0, addr);
fn connect(i: int, addr: SocketAddr) {
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
if i == MAX { return }
iotest!(fn multiple_connect_interleaved_lazy_schedule_ip4() {
static MAX: int = 10;
let addr = next_test_ip4();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
connect(0, addr);
fn connect(i: int, addr: SocketAddr) {
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
if i == MAX { return }
iotest!(fn multiple_connect_interleaved_lazy_schedule_ip6() {
static MAX: int = 10;
let addr = next_test_ip6();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
connect(0, addr);
fn connect(i: int, addr: SocketAddr) {
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
if i == MAX { return }
})
pub fn socket_name(addr: SocketAddr) {
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut listener = TcpListener::bind(ip_str.as_slice(), port).unwrap();
}
pub fn peer_name(addr: SocketAddr) {
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
spawn(proc() {
let port = addr.port;
let (tx, rx) = channel();
spawn(proc() {
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let mut srv = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
tx.send(());
let mut cl = srv.accept().unwrap();
});
rx.recv();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let mut c = TcpStream::connect(ip_str.as_slice(), port).unwrap();
let mut b = [0, ..10];
assert_eq!(c.read(b), Ok(1));
iotest!(fn double_bind() {
let addr = next_test_ip4();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let listener = TcpListener::bind(ip_str.as_slice(), port).unwrap().listen();
assert!(listener.is_ok());
let (tx, rx) = channel();
spawn(proc() {
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
rx.recv();
let _stream = TcpStream::connect(ip_str.as_slice(), port).unwrap();
// Close
});
{
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
tx.send(());
{
}
// Close listener
}
- let _listener = TcpListener::bind(addr.ip.to_str().as_slice(), port);
+ let _listener = TcpListener::bind(addr.ip.to_string().as_slice(), port);
})
iotest!(fn tcp_clone_smoke() {
let addr = next_test_ip4();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
iotest!(fn tcp_clone_two_read() {
let addr = next_test_ip6();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
let (tx1, rx) = channel();
iotest!(fn tcp_clone_two_write() {
let addr = next_test_ip4();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut acceptor = TcpListener::bind(ip_str.as_slice(), port).listen();
use rt::rtio::RtioTcpStream;
let addr = next_test_ip4();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let a = TcpListener::bind(ip_str.as_slice(), port).unwrap().listen();
spawn(proc() {
iotest!(fn accept_timeout() {
let addr = next_test_ip4();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut a = TcpListener::bind(ip_str.as_slice(), port).unwrap().listen().unwrap();
if !cfg!(target_os = "freebsd") {
let (tx, rx) = channel();
spawn(proc() {
- tx.send(TcpStream::connect(addr.ip.to_str().as_slice(),
+ tx.send(TcpStream::connect(addr.ip.to_string().as_slice(),
port).unwrap());
});
let _l = rx.recv();
// Unset the timeout and make sure that this always blocks.
a.set_timeout(None);
spawn(proc() {
- drop(TcpStream::connect(addr.ip.to_str().as_slice(),
+ drop(TcpStream::connect(addr.ip.to_string().as_slice(),
port).unwrap());
});
a.accept().unwrap();
iotest!(fn close_readwrite_smoke() {
let addr = next_test_ip4();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
let (_tx, rx) = channel::<()>();
iotest!(fn close_read_wakes_up() {
let addr = next_test_ip4();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
let (_tx, rx) = channel::<()>();
iotest!(fn readwrite_timeouts() {
let addr = next_test_ip6();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
let (tx, rx) = channel::<()>();
iotest!(fn read_timeouts() {
let addr = next_test_ip6();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
let (tx, rx) = channel::<()>();
iotest!(fn write_timeouts() {
let addr = next_test_ip6();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
let (tx, rx) = channel::<()>();
iotest!(fn timeout_concurrent_read() {
let addr = next_test_ip6();
- let ip_str = addr.ip.to_str();
+ let ip_str = addr.ip.to_string();
let port = addr.port;
let mut a = TcpListener::bind(ip_str.as_slice(), port).listen().unwrap();
let (tx, rx) = channel::<()>();
iotest!(fn clone_while_reading() {
let addr = next_test_ip6();
- let listen = TcpListener::bind(addr.ip.to_str().as_slice(), addr.port);
+ let listen = TcpListener::bind(addr.ip.to_string().as_slice(), addr.port);
let mut accept = listen.listen().unwrap();
// Enqueue a task to write to a socket
let (txdone, rxdone) = channel();
let txdone2 = txdone.clone();
spawn(proc() {
- let mut tcp = TcpStream::connect(addr.ip.to_str().as_slice(),
+ let mut tcp = TcpStream::connect(addr.ip.to_string().as_slice(),
addr.port).unwrap();
rx.recv();
tcp.write_u8(0).unwrap();
use io::net::ip::{SocketAddr, IpAddr};
use io::{Reader, Writer, IoResult, IoError};
use kinds::Send;
-use owned::Box;
+use boxed::Box;
use option::Option;
use result::{Ok, Err};
use rt::rtio::{RtioSocket, RtioUdpSocket, IoFactory, LocalIo};
use clone::Clone;
use io::{Listener, Acceptor, Reader, Writer, IoResult, IoError};
use kinds::Send;
-use owned::Box;
+use boxed::Box;
use rt::rtio::{IoFactory, LocalIo, RtioUnixListener};
use rt::rtio::{RtioUnixAcceptor, RtioPipe};
use io::{IoResult, IoError};
use libc;
use os;
-use owned::Box;
+use boxed::Box;
use rt::rtio::{RtioPipe, LocalIo};
/// A synchronous, in-memory pipe.
use str;
use fmt;
+use os;
use io::{IoResult, IoError};
use io;
use libc;
use mem;
-use owned::Box;
+use boxed::Box;
use rt::rtio::{RtioProcess, ProcessConfig, IoFactory, LocalIo};
use rt::rtio;
use c_str::CString;
+use collections::HashMap;
/// Signal a process to exit, without forcibly killing it. Corresponds to
/// SIGTERM on unix platforms.
pub extra_io: Vec<Option<io::PipeStream>>,
}
+/// A HashMap representation of environment variables.
+pub type EnvMap = HashMap<CString, CString>;
+
/// The `Command` type acts as a process builder, providing fine-grained control
/// over how a new process should be spawned. A default configuration can be
/// generated using `Command::new(program)`, where `program` gives a path to the
///
/// let output = process.stdout.get_mut_ref().read_to_end();
/// ```
+#[deriving(Clone)]
pub struct Command {
// The internal data for the builder. Documented by the builder
// methods below, and serialized into rt::rtio::ProcessConfig.
program: CString,
args: Vec<CString>,
- env: Option<Vec<(CString, CString)>>,
+ env: Option<EnvMap>,
cwd: Option<CString>,
stdin: StdioContainer,
stdout: StdioContainer,
}
/// Add an argument to pass to the program.
- pub fn arg<'a, T:ToCStr>(&'a mut self, arg: T) -> &'a mut Command {
+ pub fn arg<'a, T: ToCStr>(&'a mut self, arg: T) -> &'a mut Command {
self.args.push(arg.to_c_str());
self
}
/// Add multiple arguments to pass to the program.
- pub fn args<'a, T:ToCStr>(&'a mut self, args: &[T]) -> &'a mut Command {
+ pub fn args<'a, T: ToCStr>(&'a mut self, args: &[T]) -> &'a mut Command {
self.args.extend(args.iter().map(|arg| arg.to_c_str()));;
self
}
+ // Get a mutable borrow of the environment variable map for this `Command`.
+ fn get_env_map<'a>(&'a mut self) -> &'a mut EnvMap {
+ match self.env {
+ Some(ref mut map) => map,
+ None => {
+ // if the env is currently just inheriting from the parent's,
+ // materialize the parent's env into a hashtable.
+ self.env = Some(os::env_as_bytes().move_iter()
+ .map(|(k, v)| (k.as_slice().to_c_str(),
+ v.as_slice().to_c_str()))
+ .collect());
+ self.env.as_mut().unwrap()
+ }
+ }
+ }
- /// Sets the environment for the child process (rather than inheriting it
- /// from the current process).
-
- // FIXME (#13851): We should change this interface to allow clients to (1)
- // build up the env vector incrementally and (2) allow both inheriting the
- // current process's environment AND overriding/adding additional
- // environment variables. The underlying syscalls assume that the
- // environment has no duplicate names, so we really want to use a hashtable
- // to compute the environment to pass down to the syscall; resolving issue
- // #13851 will make it possible to use the standard hashtable.
- pub fn env<'a, T:ToCStr>(&'a mut self, env: &[(T,T)]) -> &'a mut Command {
- self.env = Some(env.iter().map(|&(ref name, ref val)| {
- (name.to_c_str(), val.to_c_str())
- }).collect());
+ /// Inserts or updates an environment variable mapping.
+ pub fn env<'a, T: ToCStr, U: ToCStr>(&'a mut self, key: T, val: U)
+ -> &'a mut Command {
+ self.get_env_map().insert(key.to_c_str(), val.to_c_str());
+ self
+ }
+
+ /// Removes an environment variable mapping.
+ pub fn env_remove<'a, T: ToCStr>(&'a mut self, key: T) -> &'a mut Command {
+ self.get_env_map().remove(&key.to_c_str());
+ self
+ }
+
+ /// Sets the entire environment map for the child process.
+ ///
+ /// If the given slice contains multiple instances of an environment
+ /// variable, the *rightmost* instance will determine the value.
+ pub fn env_set_all<'a, T: ToCStr, U: ToCStr>(&'a mut self, env: &[(T,U)])
+ -> &'a mut Command {
+ self.env = Some(env.iter().map(|&(ref k, ref v)| (k.to_c_str(), v.to_c_str()))
+ .collect());
self
}
let extra_io: Vec<rtio::StdioContainer> =
self.extra_io.iter().map(|x| to_rtio(*x)).collect();
LocalIo::maybe_raise(|io| {
+ let env = match self.env {
+ None => None,
+ Some(ref env_map) =>
+ Some(env_map.iter().collect::<Vec<_>>())
+ };
let cfg = ProcessConfig {
program: &self.program,
args: self.args.as_slice(),
- env: self.env.as_ref().map(|env| env.as_slice()),
+ env: env.as_ref().map(|e| e.as_slice()),
cwd: self.cwd.as_ref(),
stdin: to_rtio(self.stdin),
stdout: to_rtio(self.stdout),
}
/// Describes what to do with a standard io stream for a child process.
+#[deriving(Clone)]
pub enum StdioContainer {
/// This stream will be ignored. This is the equivalent of attaching the
/// stream to `/dev/null`
})
pub fn read_all(input: &mut Reader) -> String {
- input.read_to_str().unwrap()
+ input.read_to_string().unwrap()
}
pub fn run_output(cmd: Command) -> String {
}
})
- iotest!(fn test_add_to_env() {
+ iotest!(fn test_override_env() {
let new_env = vec![("RUN_TEST_NEW_ENV", "123")];
- let prog = env_cmd().env(new_env.as_slice()).spawn().unwrap();
+ let prog = env_cmd().env_set_all(new_env.as_slice()).spawn().unwrap();
let result = prog.wait_with_output().unwrap();
let output = str::from_utf8_lossy(result.output.as_slice()).into_string();
"didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output);
})
+ iotest!(fn test_add_to_env() {
+ let prog = env_cmd().env("RUN_TEST_NEW_ENV", "123").spawn().unwrap();
+ let result = prog.wait_with_output().unwrap();
+ let output = str::from_utf8_lossy(result.output.as_slice()).into_string();
+
+ assert!(output.as_slice().contains("RUN_TEST_NEW_ENV=123"),
+ "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output);
+ })
+
+ iotest!(fn test_remove_from_env() {
+ use os;
+
+ // save original environment
+ let old_env = os::getenv("RUN_TEST_NEW_ENV");
+
+ os::setenv("RUN_TEST_NEW_ENV", "123");
+ let prog = env_cmd().env_remove("RUN_TEST_NEW_ENV").spawn().unwrap();
+ let result = prog.wait_with_output().unwrap();
+ let output = str::from_utf8_lossy(result.output.as_slice()).into_string();
+
+ // restore original environment
+ match old_env {
+ None => {
+ os::unsetenv("RUN_TEST_NEW_ENV");
+ }
+ Some(val) => {
+ os::setenv("RUN_TEST_NEW_ENV", val.as_slice());
+ }
+ }
+
+ assert!(!output.as_slice().contains("RUN_TEST_NEW_ENV"),
+ "found RUN_TEST_NEW_ENV inside of:\n\n{}", output);
+ })
+
#[cfg(unix)]
pub fn sleeper() -> Process {
Command::new("sleep").arg("1000").spawn().unwrap()
use kinds::Send;
use mem::drop;
use option::{Some, None};
-use owned::Box;
+use boxed::Box;
use result::{Ok, Err};
use rt::rtio::{IoFactory, LocalIo, RtioSignal, Callback};
use slice::ImmutableVector;
use kinds::Send;
use libc;
use option::{Option, Some, None};
-use owned::Box;
+use boxed::Box;
use result::{Ok, Err};
use rt;
use rt::local::Local;
set_stdout(box w);
println!("hello!");
});
- assert_eq!(r.read_to_str().unwrap(), "hello!\n".to_string());
+ assert_eq!(r.read_to_string().unwrap(), "hello!\n".to_string());
})
iotest!(fn capture_stderr() {
::realstd::io::stdio::set_stderr(box w);
fail!("my special message");
});
- let s = r.read_to_str().unwrap();
+ let s = r.read_to_string().unwrap();
assert!(s.as_slice().contains("my special message"));
})
}
use comm::{Receiver, Sender, channel};
use io::{IoResult, IoError};
use kinds::Send;
-use owned::Box;
+use boxed::Box;
use rt::rtio::{IoFactory, LocalIo, RtioTimer, Callback};
/// A synchronous timer object
use prelude::*;
use cmp;
use io;
-use owned::Box;
+use boxed::Box;
use slice::bytes::MutableByteVector;
/// Wraps a `Reader`, limiting the number of bytes that can be read from it.
mod test {
use io::{MemReader, MemWriter, BufReader};
use io;
- use owned::Box;
+ use boxed::Box;
use super::*;
use prelude::*;
let mut r = BufReader::new(data.as_bytes());
{
let mut r = LimitReader::new(r.by_ref(), 3);
- assert_eq!(r.read_line(), Ok("012".to_str()));
+ assert_eq!(r.read_line(), Ok("012".to_string()));
assert_eq!(r.limit(), 0);
assert_eq!(r.read_line().err().unwrap().kind, io::EndOfFile);
}
{
let mut r = LimitReader::new(r.by_ref(), 9);
- assert_eq!(r.read_line(), Ok("3456789\n".to_str()));
+ assert_eq!(r.read_line(), Ok("3456789\n".to_string()));
assert_eq!(r.limit(), 1);
- assert_eq!(r.read_line(), Ok("0".to_str()));
+ assert_eq!(r.read_line(), Ok("0".to_string()));
}
{
let mut r = LimitReader::new(r.by_ref(), 100);
assert_eq!(r.read_char(), Ok('1'));
assert_eq!(r.limit(), 99);
- assert_eq!(r.read_line(), Ok("23456789\n".to_str()));
+ assert_eq!(r.read_line(), Ok("23456789\n".to_string()));
}
}
//! passing. [`sync`](sync/index.html) contains further, primitive, shared
//! memory types, including [`atomics`](sync/atomics/index.html).
//!
-//! Common types of I/O, including files, TCP, UPD, pipes, Unix domain sockets,
+//! Common types of I/O, including files, TCP, UDP, pipes, Unix domain sockets,
//! timers, and process spawning, are defined in the [`io`](io/index.html) module.
//!
//! Rust's I/O and concurrency depends on a small runtime interface
//! all the standard macros, such as `assert!`, `fail!`, `println!`,
//! and `format!`, also available to all Rust code.
-#![crate_id = "std#0.11.0"]
+#![crate_name = "std"]
#![unstable]
#![comment = "The Rust standard library"]
#![license = "MIT/ASL2"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
#![feature(macro_rules, globs, managed_boxes, linkage)]
#[cfg(test)] #[phase(plugin, link)] extern crate log;
extern crate alloc;
+extern crate unicode;
extern crate core;
extern crate core_collections = "collections";
extern crate core_rand = "rand";
#[cfg(test)] pub use realstd::ops;
#[cfg(test)] pub use realstd::cmp;
#[cfg(test)] pub use realstd::ty;
-#[cfg(test)] pub use realstd::owned;
+#[cfg(test)] pub use realstd::boxed;
#[cfg(test)] pub use realstd::gc;
pub use core::any;
pub use core::bool;
pub use core::cell;
-pub use core::char;
pub use core::clone;
#[cfg(not(test))] pub use core::cmp;
pub use core::default;
pub use core::result;
pub use core::option;
-pub use alloc::owned;
+pub use alloc::boxed;
+#[deprecated = "use boxed instead"]
+pub use owned = boxed;
+
pub use alloc::rc;
pub use core_collections::slice;
pub use rustrt::c_str;
pub use rustrt::local_data;
+pub use unicode::char;
+
pub use core_sync::comm;
// Run tests with libgreen instead of libnative.
// The test runner requires std::slice::Vector, so re-export std::slice just for it.
#[cfg(test)] pub use slice;
}
-
-#[deprecated]
-#[allow(missing_doc)]
-#[doc(hiden)]
-pub mod unstable {
- #[deprecated = "use std::dynamic_lib"]
- pub use dynamic_lib;
-}
///
/// * num - The float value
#[inline]
-pub fn to_str(num: f32) -> String {
+pub fn to_string(num: f32) -> String {
let (r, _) = strconv::float_to_str_common(
num, 10u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false);
r
///
/// * num - The float value
#[inline]
-pub fn to_str(num: f64) -> String {
+pub fn to_string(num: f64) -> String {
let (r, _) = strconv::float_to_str_common(
num, 10u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false);
r
/// Convert to a string as a byte slice in a given base.
///
-/// Use in place of x.to_str() when you do not need to store the string permanently
+/// Use in place of x.to_string() when you do not need to store the string permanently
///
/// # Examples
///
}
#[test]
- fn test_to_str() {
+ fn test_to_string() {
assert_eq!((0 as $T).to_str_radix(10u), "0".to_string());
assert_eq!((1 as $T).to_str_radix(10u), "1".to_string());
assert_eq!((-1 as $T).to_str_radix(10u), "-1".to_string());
#[test]
fn test_int_to_str_overflow() {
let mut i8_val: i8 = 127_i8;
- assert_eq!(i8_val.to_str(), "127".to_string());
+ assert_eq!(i8_val.to_string(), "127".to_string());
i8_val += 1 as i8;
- assert_eq!(i8_val.to_str(), "-128".to_string());
+ assert_eq!(i8_val.to_string(), "-128".to_string());
let mut i16_val: i16 = 32_767_i16;
- assert_eq!(i16_val.to_str(), "32767".to_string());
+ assert_eq!(i16_val.to_string(), "32767".to_string());
i16_val += 1 as i16;
- assert_eq!(i16_val.to_str(), "-32768".to_string());
+ assert_eq!(i16_val.to_string(), "-32768".to_string());
let mut i32_val: i32 = 2_147_483_647_i32;
- assert_eq!(i32_val.to_str(), "2147483647".to_string());
+ assert_eq!(i32_val.to_string(), "2147483647".to_string());
i32_val += 1 as i32;
- assert_eq!(i32_val.to_str(), "-2147483648".to_string());
+ assert_eq!(i32_val.to_string(), "-2147483648".to_string());
let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
- assert_eq!(i64_val.to_str(), "9223372036854775807".to_string());
+ assert_eq!(i64_val.to_string(), "9223372036854775807".to_string());
i64_val += 1 as i64;
- assert_eq!(i64_val.to_str(), "-9223372036854775808".to_string());
+ assert_eq!(i64_val.to_string(), "-9223372036854775808".to_string());
}
#[test]
/**
* Converts an integral number to its string representation as a byte vector.
* This is meant to be a common base implementation for all integral string
- * conversion functions like `to_str()` or `to_str_radix()`.
+ * conversion functions like `to_string()` or `to_str_radix()`.
*
* # Arguments
* - `num` - The number to convert. Accepts any number that
/**
* Converts a number to its string representation as a byte vector.
* This is meant to be a common base implementation for all numeric string
- * conversion functions like `to_str()` or `to_str_radix()`.
+ * conversion functions like `to_string()` or `to_str_radix()`.
*
* # Arguments
* - `num` - The number to convert. Accepts any number that
use f64;
#[bench]
- fn float_to_str(b: &mut Bencher) {
+ fn float_to_string(b: &mut Bencher) {
let mut rng = weak_rng();
- b.iter(|| { f64::to_str(rng.gen()); })
+ b.iter(|| { f64::to_string(rng.gen()); })
}
}
}
/// Convert to a string as a byte slice in a given base.
///
-/// Use in place of x.to_str() when you do not need to store the string permanently
+/// Use in place of x.to_string() when you do not need to store the string permanently
///
/// # Examples
///
use u16;
#[test]
- pub fn test_to_str() {
+ pub fn test_to_string() {
assert_eq!((0 as $T).to_str_radix(10u), "0".to_string());
assert_eq!((1 as $T).to_str_radix(10u), "1".to_string());
assert_eq!((2 as $T).to_str_radix(10u), "2".to_string());
#[test]
fn test_uint_to_str_overflow() {
let mut u8_val: u8 = 255_u8;
- assert_eq!(u8_val.to_str(), "255".to_string());
+ assert_eq!(u8_val.to_string(), "255".to_string());
u8_val += 1 as u8;
- assert_eq!(u8_val.to_str(), "0".to_string());
+ assert_eq!(u8_val.to_string(), "0".to_string());
let mut u16_val: u16 = 65_535_u16;
- assert_eq!(u16_val.to_str(), "65535".to_string());
+ assert_eq!(u16_val.to_string(), "65535".to_string());
u16_val += 1 as u16;
- assert_eq!(u16_val.to_str(), "0".to_string());
+ assert_eq!(u16_val.to_string(), "0".to_string());
let mut u32_val: u32 = 4_294_967_295_u32;
- assert_eq!(u32_val.to_str(), "4294967295".to_string());
+ assert_eq!(u32_val.to_string(), "4294967295".to_string());
u32_val += 1 as u32;
- assert_eq!(u32_val.to_str(), "0".to_string());
+ assert_eq!(u32_val.to_string(), "0".to_string());
let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
- assert_eq!(u64_val.to_str(), "18446744073709551615".to_string());
+ assert_eq!(u64_val.to_string(), "18446744073709551615".to_string());
u64_val += 1 as u64;
- assert_eq!(u64_val.to_str(), "0".to_string());
+ assert_eq!(u64_val.to_string(), "0".to_string());
}
#[test]
/// ```
pub fn env() -> Vec<(String,String)> {
env_as_bytes().move_iter().map(|(k,v)| {
- let k = str::from_utf8_lossy(k.as_slice()).to_string();
- let v = str::from_utf8_lossy(v.as_slice()).to_string();
+ let k = String::from_str(str::from_utf8_lossy(k.as_slice()).as_slice());
+ let v = String::from_str(str::from_utf8_lossy(v.as_slice()).as_slice());
(k,v)
}).collect()
}
/// }
/// ```
pub fn getenv(n: &str) -> Option<String> {
- getenv_as_bytes(n).map(|v| str::from_utf8_lossy(v.as_slice()).to_string())
+ getenv_as_bytes(n).map(|v| String::from_str(str::from_utf8_lossy(v.as_slice()).as_slice()))
}
#[cfg(unix)]
}
}
-/**
- * Convert a relative path to an absolute path
- *
- * If the given path is relative, return it prepended with the current working
- * directory. If the given path is already an absolute path, return it
- * as is.
- */
+///
+/// Convert a relative path to an absolute path
+///
+/// If the given path is relative, return it prepended with the current working
+/// directory. If the given path is already an absolute path, return it
+/// as is.
+///
+/// # Example
+/// ```rust
+/// use std::os;
+/// use std::path::Path;
+///
+/// // Assume we're in a path like /home/someuser
+/// let rel_path = Path::new("..");
+/// let abs_path = os::make_absolute(&rel_path);
+/// println!("The absolute path is {}", abs_path.display());
+/// // Prints "The absolute path is /home"
+/// ```
// NB: this is here rather than in path because it is a form of environment
// querying; what it does depends on the process working directory, not just
// the input paths.
/// Changes the current working directory to the specified path, returning
/// whether the change was completed successfully or not.
+///
+/// # Example
+/// ```rust
+/// use std::os;
+/// use std::path::Path;
+///
+/// let root = Path::new("/");
+/// assert!(os::change_dir(&root));
+/// println!("Succesfully changed working directory to {}!", root.display());
+/// ```
pub fn change_dir(p: &Path) -> bool {
return chdir(p);
}
/// Return the string corresponding to an `errno()` value of `errnum`.
+/// # Example
+/// ```rust
+/// use std::os;
+///
+/// // Same as println!("{}", last_os_error());
+/// println!("{}", os::error_string(os::errno() as uint));
+/// ```
pub fn error_string(errnum: uint) -> String {
return strerror(errnum);
///
/// The arguments are interpreted as utf-8, with invalid bytes replaced with \uFFFD.
/// See `str::from_utf8_lossy` for details.
+/// # Example
+///
+/// ```rust
+/// use std::os;
+///
+/// // Prints each argument on a separate line
+/// for argument in os::args().iter() {
+/// println!("{}", argument);
+/// }
+/// ```
pub fn args() -> Vec<String> {
real_args()
}
/// The memory map is released (unmapped) when the destructor is run, so don't
/// let it leave scope by accident if you want it to stick around.
pub struct MemoryMap {
- /// Pointer to the memory created or modified by this map.
- pub data: *mut u8,
- /// Number of bytes this map applies to
- pub len: uint,
- /// Type of mapping
- pub kind: MemoryMapKind,
+ data: *mut u8,
+ len: uint,
+ kind: MemoryMapKind,
}
/// Type of memory map
}
}
+impl MemoryMap {
+ /// Returns the pointer to the memory created or modified by this map.
+ pub fn data(&self) -> *mut u8 { self.data }
+ /// Returns the number of bytes this map applies to.
+ pub fn len(&self) -> uint { self.len }
+ /// Returns the type of mapping this represents.
+ pub fn kind(&self) -> MemoryMapKind { self.kind }
+}
+
#[cfg(target_os = "linux")]
pub mod consts {
pub use os::arch_consts::ARCH;
use c_str::{CString, ToCStr};
use clone::Clone;
-use cmp::{PartialEq, Eq};
+use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
use collections::Collection;
use from_str::FromStr;
use hash;
impl Eq for Path {}
+impl PartialOrd for Path {
+ fn partial_cmp(&self, other: &Path) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl Ord for Path {
+ fn cmp(&self, other: &Path) -> Ordering {
+ self.repr.cmp(&other.repr)
+ }
+}
+
impl FromStr for Path {
fn from_str(s: &str) -> Option<Path> {
Path::new_opt(s)
($path:expr, $disp:ident, $exp:expr) => (
{
let path = Path::new($path);
- assert!(path.$disp().to_str().as_slice() == $exp);
+ assert!(path.$disp().to_string().as_slice() == $exp);
}
)
)
use ascii::AsciiCast;
use c_str::{CString, ToCStr};
use clone::Clone;
-use cmp::{PartialEq, Eq};
+use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
use collections::Collection;
use from_str::FromStr;
use hash;
use slice::{Vector, ImmutableVector};
use str::{CharSplits, Str, StrAllocating, StrVector, StrSlice};
use string::String;
+use unicode::UnicodeChar;
use vec::Vec;
use super::{contains_nul, BytesContainer, GenericPath, GenericPathUnsafe};
impl Eq for Path {}
+impl PartialOrd for Path {
+ fn partial_cmp(&self, other: &Path) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl Ord for Path {
+ fn cmp(&self, other: &Path) -> Ordering {
+ self.repr.cmp(&other.repr)
+ }
+}
+
impl FromStr for Path {
fn from_str(s: &str) -> Option<Path> {
Path::new_opt(s)
let idx = path.find('\\');
if idx == Some(2) && path.as_bytes()[1] == ':' as u8 {
let c = path.as_bytes()[0];
- if c.is_ascii() && ::char::is_alphabetic(c as char) {
+ if c.is_ascii() && (c as char).is_alphabetic() {
// \\?\C:\ path
return Some(VerbatimDiskPrefix);
}
} else if path.len() > 1 && path.as_bytes()[1] == ':' as u8 {
// C:
let c = path.as_bytes()[0];
- if c.is_ascii() && ::char::is_alphabetic(c as char) {
+ if c.is_ascii() && (c as char).is_alphabetic() {
return Some(DiskPrefix);
}
}
#[test]
fn test_display_str() {
let path = Path::new("foo");
- assert_eq!(path.display().to_str(), "foo".to_string());
+ assert_eq!(path.display().to_string(), "foo".to_string());
let path = Path::new(b"\\");
- assert_eq!(path.filename_display().to_str(), "".to_string());
+ assert_eq!(path.filename_display().to_string(), "".to_string());
let path = Path::new("foo");
let mo = path.display().as_maybe_owned();
#[doc(no_inline)] pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
#[doc(no_inline)] pub use ops::{BitAnd, BitOr, BitXor};
#[doc(no_inline)] pub use ops::{Drop, Deref, DerefMut};
-#[doc(no_inline)] pub use ops::{Shl, Shr, Index};
+#[doc(no_inline)] pub use ops::{Shl, Shr};
+#[doc(no_inline)] pub use ops::{Index, IndexMut};
#[doc(no_inline)] pub use option::{Option, Some, None};
#[doc(no_inline)] pub use result::{Result, Ok, Err};
#[doc(no_inline)] pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv};
#[doc(no_inline)] pub use num::{Signed, Unsigned, Primitive, Int, Float};
#[doc(no_inline)] pub use num::{FloatMath, ToPrimitive, FromPrimitive};
-#[doc(no_inline)] pub use owned::Box;
+#[doc(no_inline)] pub use boxed::Box;
#[doc(no_inline)] pub use path::{GenericPath, Path, PosixPath, WindowsPath};
#[doc(no_inline)] pub use ptr::RawPtr;
#[doc(no_inline)] pub use io::{Buffer, Writer, Reader, Seek};
#[doc(no_inline)] pub use str::{Str, StrVector, StrSlice, OwnedStr};
#[doc(no_inline)] pub use str::{IntoMaybeOwned, StrAllocating};
-#[doc(no_inline)] pub use to_str::{ToStr, IntoStr};
+#[doc(no_inline)] pub use to_str::{ToString, IntoStr};
#[doc(no_inline)] pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4};
#[doc(no_inline)] pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8};
#[doc(no_inline)] pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12};
#[doc(no_inline)] pub use slice::{Vector, VectorVector};
#[doc(no_inline)] pub use slice::MutableVectorAllocating;
#[doc(no_inline)] pub use string::String;
+#[doc(no_inline)] pub use unicode::{UnicodeChar, UnicodeStrSlice};
#[doc(no_inline)] pub use vec::Vec;
// Reexported runtime types
#![allow(non_camel_case_types)]
-use char::Char;
use collections::Collection;
use from_str::from_str;
use io::{IoResult, Writer};
use result::{Ok, Err};
use str::StrSlice;
use sync::atomics;
+use unicode::UnicodeChar;
pub use self::imp::write;
use slice::{MutableVector};
extern {
- fn backtrace(buf: *mut *const libc::c_void,
+ fn backtrace(buf: *mut *mut libc::c_void,
sz: libc::c_int) -> libc::c_int;
}
try!(writeln!(w, "stack backtrace:"));
// 100 lines should be enough
static SIZE: libc::c_int = 100;
- let mut buf: [*const libc::c_void, ..SIZE] = unsafe {mem::zeroed()};
+ let mut buf: [*mut libc::c_void, ..SIZE] = unsafe {mem::zeroed()};
let cnt = unsafe { backtrace(buf.as_mut_ptr(), SIZE) as uint};
// skipping the first one as it is write itself
use io::{Writer, stdio};
use kinds::{Send, marker};
use option::{None, Some, Option};
-use owned::Box;
+use boxed::Box;
use result::Result;
use rt::local::Local;
use rt::task;
#[cfg(test)]
mod test {
use any::{Any, AnyRefExt};
- use owned::AnyOwnExt;
+ use boxed::BoxAny;
use result;
use result::{Ok, Err};
use str::StrAllocating;
Err(e) => {
type T = &'static str;
assert!(e.is::<T>());
- assert_eq!(*e.move::<T>().unwrap(), "static string");
+ assert_eq!(*e.downcast::<T>().unwrap(), "static string");
}
Ok(()) => fail!()
}
Err(e) => {
type T = String;
assert!(e.is::<T>());
- assert_eq!(*e.move::<T>().unwrap(), "owned string".to_string());
+ assert_eq!(*e.downcast::<T>().unwrap(), "owned string".to_string());
}
Ok(()) => fail!()
}
Err(e) => {
type T = Box<Any + Send>;
assert!(e.is::<T>());
- let any = e.move::<T>().unwrap();
+ let any = e.downcast::<T>().unwrap();
assert!(any.is::<u16>());
- assert_eq!(*any.move::<u16>().unwrap(), 413u16);
+ assert_eq!(*any.downcast::<u16>().unwrap(), 413u16);
}
Ok(()) => fail!()
}
});
assert!(r.is_ok());
- let output = reader.read_to_str().unwrap();
+ let output = reader.read_to_string().unwrap();
assert_eq!(output, "Hello, world!".to_string());
}
/*!
-The `ToStr` trait for converting to strings
+The `ToString` trait for converting to strings
*/
use string::String;
/// A generic trait for converting a value to a string
-pub trait ToStr {
+pub trait ToString {
/// Converts the value of `self` to an owned string
- fn to_str(&self) -> String;
+ fn to_string(&self) -> String;
}
/// Trait for converting a type to a string, consuming it in the process.
pub trait IntoStr {
/// Consume and convert to a string.
- fn into_str(self) -> String;
+ fn into_string(self) -> String;
}
-impl<T: fmt::Show> ToStr for T {
- fn to_str(&self) -> String {
+impl<T: fmt::Show> ToString for T {
+ fn to_string(&self) -> String {
format!("{}", *self)
}
}
#[test]
fn test_simple_types() {
- assert_eq!(1i.to_str(), "1".to_string());
- assert_eq!((-1i).to_str(), "-1".to_string());
- assert_eq!(200u.to_str(), "200".to_string());
- assert_eq!(2u8.to_str(), "2".to_string());
- assert_eq!(true.to_str(), "true".to_string());
- assert_eq!(false.to_str(), "false".to_string());
- assert_eq!(().to_str(), "()".to_string());
- assert_eq!(("hi".to_string()).to_str(), "hi".to_string());
+ assert_eq!(1i.to_string(), "1".to_string());
+ assert_eq!((-1i).to_string(), "-1".to_string());
+ assert_eq!(200u.to_string(), "200".to_string());
+ assert_eq!(2u8.to_string(), "2".to_string());
+ assert_eq!(true.to_string(), "true".to_string());
+ assert_eq!(false.to_string(), "false".to_string());
+ assert_eq!(().to_string(), "()".to_string());
+ assert_eq!(("hi".to_string()).to_string(), "hi".to_string());
}
#[test]
fn test_vectors() {
let x: Vec<int> = vec![];
- assert_eq!(x.to_str(), "[]".to_string());
- assert_eq!((vec![1i]).to_str(), "[1]".to_string());
- assert_eq!((vec![1i, 2, 3]).to_str(), "[1, 2, 3]".to_string());
- assert!((vec![vec![], vec![1i], vec![1i, 1]]).to_str() ==
+ assert_eq!(x.to_string(), "[]".to_string());
+ assert_eq!((vec![1i]).to_string(), "[1]".to_string());
+ assert_eq!((vec![1i, 2, 3]).to_string(), "[1, 2, 3]".to_string());
+ assert!((vec![vec![], vec![1i], vec![1i, 1]]).to_string() ==
"[[], [1], [1, 1]]".to_string());
}
}
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use core::mem;
pub use core::atomics::{AtomicBool, AtomicInt, AtomicUint, AtomicPtr};
use core::prelude::*;
use alloc::arc::Arc;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use core::cell::Cell;
use core::kinds::marker;
use core::mem;
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use core::mem;
use rustrt::local::Local;
use rustrt::task::{Task, BlockedTask};
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use core::cell::Cell;
use core::kinds::marker;
use core::mem;
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use core::cmp;
use core::int;
use rustrt::local::Local;
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use core::cmp;
use core::int;
use rustrt::local::Local;
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use collections::Vec;
use collections::Collection;
use core::mem;
use alloc::arc::Arc;
use alloc::heap::{allocate, deallocate};
-use alloc::owned::Box;
+use alloc::boxed::Box;
use collections::Vec;
use core::kinds::marker;
use core::mem::{forget, min_align_of, size_of, transmute};
//! use this crate specifically. Instead, its functionality is reexported
//! through `std::sync`.
-#![crate_id = "sync#0.11.0"]
+#![crate_name = "sync"]
#![experimental]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
#![feature(phase, globs, macro_rules, unsafe_destructor)]
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use core::mem;
use core::ty::Unsafe;
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use core::atomics;
use core::kinds::marker;
use core::mem;
use core::prelude::*;
-use alloc::owned::Box;
+use alloc::boxed::Box;
use core::mem;
use core::ty::Unsafe;
}
pub enum AbiArchitecture {
- RustArch, // Not a real ABI (e.g., intrinsic)
- AllArch, // An ABI that specifies cross-platform defaults (e.g., "C")
- Archs(u32) // Multiple architectures (bitset)
+ /// Not a real ABI (e.g., intrinsic)
+ RustArch,
+ /// An ABI that specifies cross-platform defaults (e.g., "C")
+ AllArch,
+ /// Multiple architectures (bitset)
+ Archs(u32)
}
static AbiDatas: &'static [AbiData] = &[
AbiData {abi: RustIntrinsic, name: "rust-intrinsic", abi_arch: RustArch},
];
-fn each_abi(op: |abi: Abi| -> bool) -> bool {
- /*!
- *
- * Iterates through each of the defined ABIs.
- */
-
- AbiDatas.iter().advance(|abi_data| op(abi_data.abi))
-}
-
+/// Returns the ABI with the given name (if any).
pub fn lookup(name: &str) -> Option<Abi> {
- /*!
- *
- * Returns the ABI with the given name (if any).
- */
-
- let mut res = None;
-
- each_abi(|abi| {
- if name == abi.data().name {
- res = Some(abi);
- false
- } else {
- true
- }
- });
- res
+ AbiDatas.iter().find(|abi_data| name == abi_data.name).map(|&x| x.abi)
}
pub fn all_names() -> Vec<&'static str> {
use abi::Abi;
use ast_util;
use owned_slice::OwnedSlice;
-use parse::token::{InternedString, special_idents, str_to_ident};
+use parse::token::{InternedString, str_to_ident};
use parse::token;
use std::fmt;
use std::gc::{Gc, GC};
use serialize::{Encodable, Decodable, Encoder, Decoder};
-/// A pointer abstraction. FIXME(eddyb) #10676 use Rc<T> in the future.
+/// A pointer abstraction.
+// FIXME(eddyb) #10676 use Rc<T> in the future.
pub type P<T> = Gc<T>;
#[allow(non_snake_case_functions)]
// FIXME #6993: in librustc, uses of "ident" should be replaced
// by just "Name".
-// an identifier contains a Name (index into the interner
-// table) and a SyntaxContext to track renaming and
-// macro expansion per Flatt et al., "Macros
-// That Work Together"
-#[deriving(Clone, Hash, PartialOrd, Eq, Ord, Show)]
+/// An identifier contains a Name (index into the interner
+/// table) and a SyntaxContext to track renaming and
+/// macro expansion per Flatt et al., "Macros
+/// That Work Together"
+#[deriving(Clone, Hash, PartialOrd, Eq, Ord)]
pub struct Ident {
pub name: Name,
pub ctxt: SyntaxContext
impl Ident {
/// Construct an identifier with the given name and an empty context:
pub fn new(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT}}
+
+ pub fn as_str<'a>(&'a self) -> &'a str {
+ self.name.as_str()
+ }
+}
+
+impl Show for Ident {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}#{}", self.name, self.ctxt)
+ }
+}
+
+impl Show for Name {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let Name(nm) = *self;
+ write!(f, "\"{}\"({})", token::get_name(*self).get(), nm)
+ }
}
impl PartialEq for Ident {
/// A name is a part of an identifier, representing a string or gensym. It's
/// the result of interning.
-pub type Name = u32;
+#[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Encodable, Decodable, Clone)]
+pub struct Name(pub u32);
+
+impl Name {
+ pub fn as_str<'a>(&'a self) -> &'a str {
+ unsafe {
+ // FIXME #12938: can't use copy_lifetime since &str isn't a &T
+ ::std::mem::transmute(token::get_name(*self).get())
+ }
+ }
+
+ pub fn uint(&self) -> uint {
+ let Name(nm) = *self;
+ nm as uint
+ }
+
+ pub fn ident(&self) -> Ident {
+ Ident { name: *self, ctxt: 0 }
+ }
+}
/// A mark represents a unique id associated with a macro expansion
pub type Mrk = u32;
pub name: Name
}
-// a "Path" is essentially Rust's notion of a name;
-// for instance: std::cmp::PartialEq . It's represented
-// as a sequence of identifiers, along with a bunch
-// of supporting information.
+/// A "Path" is essentially Rust's notion of a name; for instance:
+/// std::cmp::PartialEq . It's represented as a sequence of identifiers,
+/// along with a bunch of supporting information.
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Path {
pub span: Span,
pub static LOCAL_CRATE: CrateNum = 0;
pub static CRATE_NODE_ID: NodeId = 0;
-// When parsing and doing expansions, we initially give all AST nodes this AST
-// node value. Then later, in the renumber pass, we renumber them to have
-// small, positive ids.
+/// When parsing and doing expansions, we initially give all AST nodes this AST
+/// node value. Then later, in the renumber pass, we renumber them to have
+/// small, positive ids.
pub static DUMMY_NODE_ID: NodeId = -1;
-// The AST represents all type param bounds as types.
-// typeck::collect::compute_bounds matches these against
-// the "special" built-in traits (see middle::lang_items) and
-// detects Copy, Send and Share.
+/// The AST represents all type param bounds as types.
+/// typeck::collect::compute_bounds matches these against
+/// the "special" built-in traits (see middle::lang_items) and
+/// detects Copy, Send and Share.
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum TyParamBound {
TraitTyParamBound(TraitRef),
pub struct TyParam {
pub ident: Ident,
pub id: NodeId,
- pub sized: Sized,
pub bounds: OwnedSlice<TyParamBound>,
+ pub unbound: Option<TyParamBound>,
pub default: Option<P<Ty>>,
pub span: Span
}
+/// Represents lifetimes and type parameters attached to a declaration
+/// of a function, enum, trait, etc.
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Generics {
pub lifetimes: Vec<Lifetime>,
}
}
-// The set of MetaItems that define the compilation environment of the crate,
-// used to drive conditional compilation
-pub type CrateConfig = Vec<Gc<MetaItem>>;
+/// The set of MetaItems that define the compilation environment of the crate,
+/// used to drive conditional compilation
+pub type CrateConfig = Vec<Gc<MetaItem>> ;
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Crate {
pub attrs: Vec<Attribute>,
pub config: CrateConfig,
pub span: Span,
+ pub exported_macros: Vec<Span>
}
pub type MetaItem = Spanned<MetaItem_>;
pub enum Pat_ {
PatWild,
PatWildMulti,
- // A PatIdent may either be a new bound variable,
- // or a nullary enum (in which case the second field
- // is None).
- // In the nullary enum case, the parser can't determine
- // which it is. The resolver determines this, and
- // records this pattern's NodeId in an auxiliary
- // set (of "PatIdents that refer to nullary enums")
+ /// A PatIdent may either be a new bound variable,
+ /// or a nullary enum (in which case the third field
+ /// is None).
+ /// In the nullary enum case, the parser can't determine
+ /// which it is. The resolver determines this, and
+ /// records this pattern's NodeId in an auxiliary
+ /// set (of "PatIdents that refer to nullary enums")
PatIdent(BindingMode, SpannedIdent, Option<Gc<Pat>>),
PatEnum(Path, Option<Vec<Gc<Pat>>>), /* "none" means a * pattern where
* we don't bind the fields to names */
PatRegion(Gc<Pat>), // reference pattern
PatLit(Gc<Expr>),
PatRange(Gc<Expr>, Gc<Expr>),
- // [a, b, ..i, y, z] is represented as
- // PatVec(~[a, b], Some(i), ~[y, z])
+ /// [a, b, ..i, y, z] is represented as:
+ /// PatVec(~[a, b], Some(i), ~[y, z])
PatVec(Vec<Gc<Pat>>, Option<Gc<Pat>>, Vec<Gc<Pat>>),
PatMac(Mac),
}
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum ExprVstore {
- ExprVstoreUniq, // ~[1,2,3,4]
- ExprVstoreSlice, // &[1,2,3,4]
- ExprVstoreMutSlice, // &mut [1,2,3,4]
+ /// ~[1, 2, 3, 4]
+ ExprVstoreUniq,
+ /// &[1, 2, 3, 4]
+ ExprVstoreSlice,
+ /// &mut [1, 2, 3, 4]
+ ExprVstoreMutSlice,
}
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum Stmt_ {
- // could be an item or a local (let) binding:
+ /// Could be an item or a local (let) binding:
StmtDecl(Gc<Decl>, NodeId),
- // expr without trailing semi-colon (must have unit type):
+ /// Expr without trailing semi-colon (must have unit type):
StmtExpr(Gc<Expr>, NodeId),
- // expr with trailing semi-colon (may have any type):
+ /// Expr with trailing semi-colon (may have any type):
StmtSemi(Gc<Expr>, NodeId),
- // bool: is there a trailing sem-colon?
+ /// bool: is there a trailing sem-colon?
StmtMac(Mac, bool),
}
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum Decl_ {
- // a local (let) binding:
+ /// A local (let) binding:
DeclLocal(Gc<Local>),
- // an item binding:
+ /// An item binding:
DeclItem(Gc<Item>),
}
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum Expr_ {
ExprVstore(Gc<Expr>, ExprVstore),
- // First expr is the place; second expr is the value.
+ /// First expr is the place; second expr is the value.
ExprBox(Gc<Expr>, Gc<Expr>),
ExprVec(Vec<Gc<Expr>>),
ExprCall(Gc<Expr>, Vec<Gc<Expr>>),
ExprCast(Gc<Expr>, P<Ty>),
ExprIf(Gc<Expr>, P<Block>, Option<Gc<Expr>>),
ExprWhile(Gc<Expr>, P<Block>),
- // FIXME #6993: change to Option<Name>
+ // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
ExprForLoop(Gc<Pat>, Gc<Expr>, P<Block>, Option<Ident>),
// Conditionless loop (can be exited with break, cont, or ret)
- // FIXME #6993: change to Option<Name>
+ // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
ExprLoop(P<Block>, Option<Ident>),
ExprMatch(Gc<Expr>, Vec<Arm>),
ExprFnBlock(P<FnDecl>, P<Block>),
ExprField(Gc<Expr>, SpannedIdent, Vec<P<Ty>>),
ExprIndex(Gc<Expr>, Gc<Expr>),
- /// Expression that looks like a "name". For example,
- /// `std::slice::from_elem::<uint>` is an ExprPath that's the "name" part
- /// of a function call.
+ /// Variable reference, possibly containing `::` and/or
+ /// type parameters, e.g. foo::bar::<baz>
ExprPath(Path),
ExprAddrOf(Mutability, Gc<Expr>),
ExprMac(Mac),
- // A struct literal expression.
+ /// A struct literal expression.
ExprStruct(Path, Vec<Field> , Option<Gc<Expr>> /* base */),
- // A vector literal constructed from one repeated element.
+ /// A vector literal constructed from one repeated element.
ExprRepeat(Gc<Expr> /* element */, Gc<Expr> /* count */),
- // No-op: used solely so we can pretty-print faithfully
+ /// No-op: used solely so we can pretty-print faithfully
ExprParen(Gc<Expr>)
}
-// When the main rust parser encounters a syntax-extension invocation, it
-// parses the arguments to the invocation as a token-tree. This is a very
-// loose structure, such that all sorts of different AST-fragments can
-// be passed to syntax extensions using a uniform type.
-//
-// If the syntax extension is an MBE macro, it will attempt to match its
-// LHS "matchers" against the provided token tree, and if it finds a
-// match, will transcribe the RHS token tree, splicing in any captured
-// macro_parser::matched_nonterminals into the TTNonterminals it finds.
-//
-// The RHS of an MBE macro is the only place a TTNonterminal or TTSeq
-// makes any real sense. You could write them elsewhere but nothing
-// else knows what to do with them, so you'll probably get a syntax
-// error.
-//
+/// When the main rust parser encounters a syntax-extension invocation, it
+/// parses the arguments to the invocation as a token-tree. This is a very
+/// loose structure, such that all sorts of different AST-fragments can
+/// be passed to syntax extensions using a uniform type.
+///
+/// If the syntax extension is an MBE macro, it will attempt to match its
+/// LHS "matchers" against the provided token tree, and if it finds a
+/// match, will transcribe the RHS token tree, splicing in any captured
+/// macro_parser::matched_nonterminals into the TTNonterminals it finds.
+///
+/// The RHS of an MBE macro is the only place a TTNonterminal or TTSeq
+/// makes any real sense. You could write them elsewhere but nothing
+/// else knows what to do with them, so you'll probably get a syntax
+/// error.
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
#[doc="For macro invocations; parsing is delegated to the macro"]
pub enum TokenTree {
- // a single token
+ /// A single token
TTTok(Span, ::parse::token::Token),
- // a delimited sequence (the delimiters appear as the first
- // and last elements of the vector)
+ /// A delimited sequence (the delimiters appear as the first
+ /// and last elements of the vector)
// FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
TTDelim(Rc<Vec<TokenTree>>),
// These only make sense for right-hand-sides of MBE macros:
- // a kleene-style repetition sequence with a span, a TTForest,
- // an optional separator, and a boolean where true indicates
- // zero or more (..), and false indicates one or more (+).
+ /// A kleene-style repetition sequence with a span, a TTForest,
+ /// an optional separator, and a boolean where true indicates
+ /// zero or more (..), and false indicates one or more (+).
// FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
TTSeq(Span, Rc<Vec<TokenTree>>, Option<::parse::token::Token>, bool),
- // a syntactic variable that will be filled in by macro expansion.
+ /// A syntactic variable that will be filled in by macro expansion.
TTNonterminal(Span, Ident)
}
-//
// Matchers are nodes defined-by and recognized-by the main rust parser and
// language, but they're only ever found inside syntax-extension invocations;
// indeed, the only thing that ever _activates_ the rules in the rust parser
//
// $( $lhs:matchers => $rhs:tt );+
//
-// If you understand that, you have closed to loop and understand the whole
+// If you understand that, you have closed the loop and understand the whole
// macro system. Congratulations.
-//
pub type Matcher = Spanned<Matcher_>;
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum Matcher_ {
- // match one token
+ /// Match one token
MatchTok(::parse::token::Token),
- // match repetitions of a sequence: body, separator, zero ok?,
- // lo, hi position-in-match-array used:
+ /// Match repetitions of a sequence: body, separator, zero ok?,
+ /// lo, hi position-in-match-array used:
MatchSeq(Vec<Matcher> , Option<::parse::token::Token>, bool, uint, uint),
- // parse a Rust NT: name to bind, name of NT, position in match array:
+ /// Parse a Rust NT: name to bind, name of NT, position in match array:
MatchNonterminal(Ident, Ident, uint)
}
pub type Mac = Spanned<Mac_>;
-// represents a macro invocation. The Path indicates which macro
-// is being invoked, and the vector of token-trees contains the source
-// of the macro invocation.
-// There's only one flavor, now, so this could presumably be simplified.
+/// Represents a macro invocation. The Path indicates which macro
+/// is being invoked, and the vector of token-trees contains the source
+/// of the macro invocation.
+/// There's only one flavor, now, so this could presumably be simplified.
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum Mac_ {
+ // NB: the additional ident for a macro_rules-style macro is actually
+ // stored in the enclosing item. Oog.
MacInvocTT(Path, Vec<TokenTree> , SyntaxContext), // new macro-invocation
}
-#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum StrStyle {
CookedStr,
RawStr(uint)
pub type Lit = Spanned<Lit_>;
-#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum Lit_ {
LitStr(InternedString, StrStyle),
LitBinary(Rc<Vec<u8> >),
pub span: Span,
}
+/// Represents a required method in a trait declaration,
+/// one without a default implementation
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct TypeMethod {
pub ident: Ident,
pub vis: Visibility,
}
-// A trait method is either required (meaning it doesn't have an
-// implementation, just a signature) or provided (meaning it has a default
-// implementation).
+/// Represents a method declaration in a trait declaration, possibly including
+/// a default implementation A trait method is either required (meaning it
+/// doesn't have an implementation, just a signature) or provided (meaning it
+/// has a default implementation).
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum TraitMethod {
Required(TypeMethod),
impl fmt::Show for IntTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}", ast_util::int_ty_to_str(*self, None))
+ write!(f, "{}", ast_util::int_ty_to_string(*self, None))
+ }
+}
+
+impl IntTy {
+ pub fn suffix_len(&self) -> uint {
+ match *self {
+ TyI => 1,
+ TyI8 => 2,
+ TyI16 | TyI32 | TyI64 => 3,
+ }
}
}
TyU64,
}
+impl UintTy {
+ pub fn suffix_len(&self) -> uint {
+ match *self {
+ TyU => 1,
+ TyU8 => 2,
+ TyU16 | TyU32 | TyU64 => 3,
+ }
+ }
+}
+
impl fmt::Show for UintTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}", ast_util::uint_ty_to_str(*self, None))
+ write!(f, "{}", ast_util::uint_ty_to_string(*self, None))
}
}
impl fmt::Show for FloatTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}", ast_util::float_ty_to_str(*self))
+ write!(f, "{}", ast_util::float_ty_to_string(*self))
+ }
+}
+
+impl FloatTy {
+ pub fn suffix_len(&self) -> uint {
+ match *self {
+ TyF32 | TyF64 => 3, // add F128 handling here
+ }
}
}
pub span: Span,
}
-// Not represented directly in the AST, referred to by name through a ty_path.
+/// Not represented directly in the AST, referred to by name through a ty_path.
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum PrimTy {
TyInt(IntTy),
}
}
+/// Represents the type of a closure
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct ClosureTy {
pub lifetimes: Vec<Lifetime>,
pub fn_style: FnStyle,
pub onceness: Onceness,
pub decl: P<FnDecl>,
- // Optional optvec distinguishes between "fn()" and "fn:()" so we can
- // implement issue #7264. None means "fn()", which means infer a default
- // bound based on pointer sigil during typeck. Some(Empty) means "fn:()",
- // which means use no bounds (e.g., not even Owned on a ~fn()).
+ /// Optional optvec distinguishes between "fn()" and "fn:()" so we can
+ /// implement issue #7264. None means "fn()", which means infer a default
+ /// bound based on pointer sigil during typeck. Some(Empty) means "fn:()",
+ /// which means use no bounds (e.g., not even Owned on a ~fn()).
pub bounds: Option<OwnedSlice<TyParamBound>>,
}
TyUnboxedFn(Gc<UnboxedFnTy>),
TyTup(Vec<P<Ty>> ),
TyPath(Path, Option<OwnedSlice<TyParamBound>>, NodeId), // for #7264; see above
- // No-op; kept solely so that we can pretty-print faithfully
+ /// No-op; kept solely so that we can pretty-print faithfully
TyParen(P<Ty>),
TyTypeof(Gc<Expr>),
- // TyInfer means the type should be inferred instead of it having been
- // specified. This can appear anywhere in a type.
+ /// TyInfer means the type should be inferred instead of it having been
+ /// specified. This can appear anywhere in a type.
TyInfer,
}
pub dialect: AsmDialect
}
+/// represents an argument in a function header
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Arg {
pub ty: P<Ty>,
}
impl Arg {
- pub fn new_self(span: Span, mutability: Mutability) -> Arg {
- let path = Spanned{span:span,node:special_idents::self_};
+ pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg {
+ let path = Spanned{span:span,node:self_ident};
Arg {
// HACK(eddyb) fake type for the self argument.
ty: P(Ty {
}
}
-// represents the header (not the body) of a function declaration
+/// represents the header (not the body) of a function declaration
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct FnDecl {
pub inputs: Vec<Arg>,
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum FnStyle {
- UnsafeFn, // declared with "unsafe fn"
- NormalFn, // declared with "fn"
+ /// Declared with "unsafe fn"
+ UnsafeFn,
+ /// Declared with "fn"
+ NormalFn,
}
impl fmt::Show for FnStyle {
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum RetStyle {
- NoReturn, // functions with return type _|_ that always
- // raise an error or exit (i.e. never return to the caller)
- Return, // everything else
+ /// Functions with return type ! that always
+ /// raise an error or exit (i.e. never return to the caller)
+ NoReturn,
+ /// Everything else
+ Return,
}
+/// Represents the kind of 'self' associated with a method
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum ExplicitSelf_ {
- SelfStatic, // no self
- SelfValue, // `self`
- SelfRegion(Option<Lifetime>, Mutability), // `&'lt self`, `&'lt mut self`
- SelfUniq // `~self`
+ /// No self
+ SelfStatic,
+ /// `self
+ SelfValue(Ident),
+ /// `&'lt self`, `&'lt mut self`
+ SelfRegion(Option<Lifetime>, Mutability, Ident),
+ /// `~self`
+ SelfUniq(Ident)
}
pub type ExplicitSelf = Spanned<ExplicitSelf_>;
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Method {
- pub ident: Ident,
pub attrs: Vec<Attribute>,
- pub generics: Generics,
- pub explicit_self: ExplicitSelf,
- pub fn_style: FnStyle,
- pub decl: P<FnDecl>,
- pub body: P<Block>,
pub id: NodeId,
pub span: Span,
- pub vis: Visibility,
+ pub node: Method_
+}
+
+#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
+pub enum Method_ {
+ /// Represents a method declaration
+ MethDecl(Ident, Generics, ExplicitSelf, FnStyle, P<FnDecl>, P<Block>, Visibility),
+ /// Represents a macro in method position
+ MethMac(Mac),
}
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum ViewPath_ {
- // quux = foo::bar::baz
- //
- // or just
- //
- // foo::bar::baz (with 'baz =' implicitly on the left)
+ /// `quux = foo::bar::baz`
+ ///
+ /// or just
+ ///
+ /// `foo::bar::baz ` (with 'baz =' implicitly on the left)
ViewPathSimple(Ident, Path, NodeId),
- // foo::bar::*
+ /// `foo::bar::*`
ViewPathGlob(Path, NodeId),
- // foo::bar::{a,b,c}
+ /// `foo::bar::{a,b,c}`
ViewPathList(Path, Vec<PathListIdent> , NodeId)
}
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum ViewItem_ {
- // ident: name used to refer to this crate in the code
- // optional (InternedString,StrStyle): if present, this is a location
- // (containing arbitrary characters) from which to fetch the crate sources
- // For example, extern crate whatever = "github.com/rust-lang/rust"
+ /// Ident: name used to refer to this crate in the code
+ /// optional (InternedString,StrStyle): if present, this is a location
+ /// (containing arbitrary characters) from which to fetch the crate sources
+ /// For example, extern crate whatever = "github.com/rust-lang/rust"
ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
ViewItemUse(Gc<ViewPath>),
}
-// Meta-data associated with an item
+/// Meta-data associated with an item
pub type Attribute = Spanned<Attribute_>;
-// Distinguishes between Attributes that decorate items and Attributes that
-// are contained as statements within items. These two cases need to be
-// distinguished for pretty-printing.
+/// Distinguishes between Attributes that decorate items and Attributes that
+/// are contained as statements within items. These two cases need to be
+/// distinguished for pretty-printing.
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum AttrStyle {
AttrOuter,
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct AttrId(pub uint);
-// doc-comments are promoted to attributes that have is_sugared_doc = true
+/// Doc-comments are promoted to attributes that have is_sugared_doc = true
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct Attribute_ {
pub id: AttrId,
pub is_sugared_doc: bool,
}
-/*
- TraitRef's appear in impls.
- resolve maps each TraitRef's ref_id to its defining trait; that's all
- that the ref_id is for. The impl_id maps to the "self type" of this impl.
- If this impl is an ItemImpl, the impl_id is redundant (it could be the
- same as the impl's node id).
- */
+
+/// TraitRef's appear in impls.
+/// resolve maps each TraitRef's ref_id to its defining trait; that's all
+/// that the ref_id is for. The impl_id maps to the "self type" of this impl.
+/// If this impl is an ItemImpl, the impl_id is redundant (it could be the
+/// same as the impl's node id).
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct TraitRef {
pub path: Path,
}
}
-#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
-pub enum Sized {
- DynSize,
- StaticSize,
-}
-
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct StructField_ {
pub kind: StructFieldKind,
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum StructFieldKind {
NamedField(Ident, Visibility),
- UnnamedField(Visibility), // element of a tuple-like struct
+ /// Element of a tuple-like struct
+ UnnamedField(Visibility),
}
impl StructFieldKind {
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct StructDef {
- pub fields: Vec<StructField>, /* fields, not including ctor */
- /* ID of the constructor. This is only used for tuple- or enum-like
- * structs. */
+ /// Fields, not including ctor
+ pub fields: Vec<StructField>,
+ /// ID of the constructor. This is only used for tuple- or enum-like
+ /// structs.
pub ctor_id: Option<NodeId>,
- pub super_struct: Option<P<Ty>>, // Super struct, if specified.
- pub is_virtual: bool, // True iff the struct may be inherited from.
+ /// Super struct, if specified.
+ pub super_struct: Option<P<Ty>>,
+ /// True iff the struct may be inherited from.
+ pub is_virtual: bool,
}
/*
ItemTy(P<Ty>, Generics),
ItemEnum(EnumDef, Generics),
ItemStruct(Gc<StructDef>, Generics),
- ItemTrait(Generics, Sized, Vec<TraitRef> , Vec<TraitMethod> ),
+ /// Represents a Trait Declaration
+ ItemTrait(Generics,
+ Option<TyParamBound>, // (optional) default bound not required for Self.
+ // Currently, only Sized makes sense here.
+ Vec<TraitRef> ,
+ Vec<TraitMethod>),
ItemImpl(Generics,
Option<TraitRef>, // (optional) trait this impl implements
P<Ty>, // self
Vec<Gc<Method>>),
- // a macro invocation (which includes macro definition)
+ /// A macro invocation (which includes macro definition)
ItemMac(Mac),
}
ForeignItemStatic(P<Ty>, /* is_mutbl */ bool),
}
-// The data we save and restore about an inlined item or method. This is not
-// part of the AST that we parse from a file, but it becomes part of the tree
-// that we trans.
+/// The data we save and restore about an inlined item or method. This is not
+/// part of the AST that we parse from a file, but it becomes part of the tree
+/// that we trans.
#[deriving(PartialEq, Eq, Encodable, Decodable, Hash)]
pub enum InlinedItem {
IIItem(Gc<Item>),
hi: BytePos(20),
expn_info: None,
},
+ exported_macros: Vec::new(),
};
// doesn't matter which encoder we use....
let _f = &e as &serialize::Encodable<json::Encoder, io::IoError>;
+++ /dev/null
-// Copyright 2012-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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use abi;
-use ast::*;
-use ast_util;
-use codemap::Span;
-use fold::Folder;
-use fold;
-use parse::token;
-use print::pprust;
-use util::small_vector::SmallVector;
-
-use std::cell::RefCell;
-use std::fmt;
-use std::gc::{Gc, GC};
-use std::iter;
-use std::slice;
-
-#[deriving(Clone, PartialEq)]
-pub enum PathElem {
- PathMod(Name),
- PathName(Name)
-}
-
-impl PathElem {
- pub fn name(&self) -> Name {
- match *self {
- PathMod(name) | PathName(name) => name
- }
- }
-}
-
-impl fmt::Show for PathElem {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let slot = token::get_name(self.name());
- write!(f, "{}", slot)
- }
-}
-
-#[deriving(Clone)]
-struct LinkedPathNode<'a> {
- node: PathElem,
- next: LinkedPath<'a>,
-}
-
-type LinkedPath<'a> = Option<&'a LinkedPathNode<'a>>;
-
-impl<'a> Iterator<PathElem> for LinkedPath<'a> {
- fn next(&mut self) -> Option<PathElem> {
- match *self {
- Some(node) => {
- *self = node.next;
- Some(node.node)
- }
- None => None
- }
- }
-}
-
-// HACK(eddyb) move this into libstd (value wrapper for slice::Items).
-#[deriving(Clone)]
-pub struct Values<'a, T>(pub slice::Items<'a, T>);
-
-impl<'a, T: Copy> Iterator<T> for Values<'a, T> {
- fn next(&mut self) -> Option<T> {
- let &Values(ref mut items) = self;
- items.next().map(|&x| x)
- }
-}
-
-/// The type of the iterator used by with_path.
-pub type PathElems<'a, 'b> = iter::Chain<Values<'a, PathElem>, LinkedPath<'b>>;
-
-pub fn path_to_str<PI: Iterator<PathElem>>(mut path: PI) -> String {
- let itr = token::get_ident_interner();
-
- path.fold(String::new(), |mut s, e| {
- let e = itr.get(e.name());
- if !s.is_empty() {
- s.push_str("::");
- }
- s.push_str(e.as_slice());
- s
- }).to_string()
-}
-
-#[deriving(Clone)]
-pub enum Node {
- NodeItem(Gc<Item>),
- NodeForeignItem(Gc<ForeignItem>),
- NodeTraitMethod(Gc<TraitMethod>),
- NodeMethod(Gc<Method>),
- NodeVariant(P<Variant>),
- NodeExpr(Gc<Expr>),
- NodeStmt(Gc<Stmt>),
- NodeArg(Gc<Pat>),
- NodeLocal(Gc<Pat>),
- NodePat(Gc<Pat>),
- NodeBlock(P<Block>),
-
- /// NodeStructCtor represents a tuple struct.
- NodeStructCtor(Gc<StructDef>),
-
- NodeLifetime(Gc<Lifetime>),
-}
-
-// The odd layout is to bring down the total size.
-#[deriving(Clone)]
-enum MapEntry {
- // Placeholder for holes in the map.
- NotPresent,
-
- // All the node types, with a parent ID.
- EntryItem(NodeId, Gc<Item>),
- EntryForeignItem(NodeId, Gc<ForeignItem>),
- EntryTraitMethod(NodeId, Gc<TraitMethod>),
- EntryMethod(NodeId, Gc<Method>),
- EntryVariant(NodeId, P<Variant>),
- EntryExpr(NodeId, Gc<Expr>),
- EntryStmt(NodeId, Gc<Stmt>),
- EntryArg(NodeId, Gc<Pat>),
- EntryLocal(NodeId, Gc<Pat>),
- EntryPat(NodeId, Gc<Pat>),
- EntryBlock(NodeId, P<Block>),
- EntryStructCtor(NodeId, Gc<StructDef>),
- EntryLifetime(NodeId, Gc<Lifetime>),
-
- // Roots for node trees.
- RootCrate,
- RootInlinedParent(P<InlinedParent>)
-}
-
-struct InlinedParent {
- path: Vec<PathElem> ,
- // Required by NodeTraitMethod and NodeMethod.
- def_id: DefId
-}
-
-impl MapEntry {
- fn parent(&self) -> Option<NodeId> {
- Some(match *self {
- EntryItem(id, _) => id,
- EntryForeignItem(id, _) => id,
- EntryTraitMethod(id, _) => id,
- EntryMethod(id, _) => id,
- EntryVariant(id, _) => id,
- EntryExpr(id, _) => id,
- EntryStmt(id, _) => id,
- EntryArg(id, _) => id,
- EntryLocal(id, _) => id,
- EntryPat(id, _) => id,
- EntryBlock(id, _) => id,
- EntryStructCtor(id, _) => id,
- EntryLifetime(id, _) => id,
- _ => return None
- })
- }
-
- fn to_node(&self) -> Option<Node> {
- Some(match *self {
- EntryItem(_, p) => NodeItem(p),
- EntryForeignItem(_, p) => NodeForeignItem(p),
- EntryTraitMethod(_, p) => NodeTraitMethod(p),
- EntryMethod(_, p) => NodeMethod(p),
- EntryVariant(_, p) => NodeVariant(p),
- EntryExpr(_, p) => NodeExpr(p),
- EntryStmt(_, p) => NodeStmt(p),
- EntryArg(_, p) => NodeArg(p),
- EntryLocal(_, p) => NodeLocal(p),
- EntryPat(_, p) => NodePat(p),
- EntryBlock(_, p) => NodeBlock(p),
- EntryStructCtor(_, p) => NodeStructCtor(p),
- EntryLifetime(_, p) => NodeLifetime(p),
- _ => return None
- })
- }
-}
-
-pub struct Map {
- /// NodeIds are sequential integers from 0, so we can be
- /// super-compact by storing them in a vector. Not everything with
- /// a NodeId is in the map, but empirically the occupancy is about
- /// 75-80%, so there's not too much overhead (certainly less than
- /// a hashmap, since they (at the time of writing) have a maximum
- /// of 75% occupancy).
- ///
- /// Also, indexing is pretty quick when you've got a vector and
- /// plain old integers.
- map: RefCell<Vec<MapEntry> >
-}
-
-impl Map {
- fn find_entry(&self, id: NodeId) -> Option<MapEntry> {
- let map = self.map.borrow();
- if map.len() > id as uint {
- Some(*map.get(id as uint))
- } else {
- None
- }
- }
-
- /// Retrieve the Node corresponding to `id`, failing if it cannot
- /// be found.
- pub fn get(&self, id: NodeId) -> Node {
- match self.find(id) {
- Some(node) => node,
- None => fail!("couldn't find node id {} in the AST map", id)
- }
- }
-
- /// Retrieve the Node corresponding to `id`, returning None if
- /// cannot be found.
- pub fn find(&self, id: NodeId) -> Option<Node> {
- self.find_entry(id).and_then(|x| x.to_node())
- }
-
- /// Retrieve the parent NodeId for `id`, or `id` itself if no
- /// parent is registered in this map.
- pub fn get_parent(&self, id: NodeId) -> NodeId {
- self.find_entry(id).and_then(|x| x.parent()).unwrap_or(id)
- }
-
- pub fn get_parent_did(&self, id: NodeId) -> DefId {
- let parent = self.get_parent(id);
- match self.find_entry(parent) {
- Some(RootInlinedParent(data)) => data.def_id,
- _ => ast_util::local_def(parent)
- }
- }
-
- pub fn get_foreign_abi(&self, id: NodeId) -> abi::Abi {
- let parent = self.get_parent(id);
- let abi = match self.find_entry(parent) {
- Some(EntryItem(_, i)) => match i.node {
- ItemForeignMod(ref nm) => Some(nm.abi),
- _ => None
- },
- // Wrong but OK, because the only inlined foreign items are intrinsics.
- Some(RootInlinedParent(_)) => Some(abi::RustIntrinsic),
- _ => None
- };
- match abi {
- Some(abi) => abi,
- None => fail!("expected foreign mod or inlined parent, found {}",
- self.node_to_str(parent))
- }
- }
-
- pub fn get_foreign_vis(&self, id: NodeId) -> Visibility {
- let vis = self.expect_foreign_item(id).vis;
- match self.find(self.get_parent(id)) {
- Some(NodeItem(i)) => vis.inherit_from(i.vis),
- _ => vis
- }
- }
-
- pub fn expect_item(&self, id: NodeId) -> Gc<Item> {
- match self.find(id) {
- Some(NodeItem(item)) => item,
- _ => fail!("expected item, found {}", self.node_to_str(id))
- }
- }
-
- pub fn expect_struct(&self, id: NodeId) -> Gc<StructDef> {
- match self.find(id) {
- Some(NodeItem(i)) => {
- match i.node {
- ItemStruct(struct_def, _) => struct_def,
- _ => fail!("struct ID bound to non-struct")
- }
- }
- Some(NodeVariant(ref variant)) => {
- match (*variant).node.kind {
- StructVariantKind(struct_def) => struct_def,
- _ => fail!("struct ID bound to enum variant that isn't struct-like"),
- }
- }
- _ => fail!(format!("expected struct, found {}", self.node_to_str(id))),
- }
- }
-
- pub fn expect_variant(&self, id: NodeId) -> P<Variant> {
- match self.find(id) {
- Some(NodeVariant(variant)) => variant,
- _ => fail!(format!("expected variant, found {}", self.node_to_str(id))),
- }
- }
-
- pub fn expect_foreign_item(&self, id: NodeId) -> Gc<ForeignItem> {
- match self.find(id) {
- Some(NodeForeignItem(item)) => item,
- _ => fail!("expected foreign item, found {}", self.node_to_str(id))
- }
- }
-
- pub fn get_path_elem(&self, id: NodeId) -> PathElem {
- match self.get(id) {
- NodeItem(item) => {
- match item.node {
- ItemMod(_) | ItemForeignMod(_) => {
- PathMod(item.ident.name)
- }
- _ => PathName(item.ident.name)
- }
- }
- NodeForeignItem(i) => PathName(i.ident.name),
- NodeMethod(m) => PathName(m.ident.name),
- NodeTraitMethod(tm) => match *tm {
- Required(ref m) => PathName(m.ident.name),
- Provided(ref m) => PathName(m.ident.name)
- },
- NodeVariant(v) => PathName(v.node.name.name),
- node => fail!("no path elem for {:?}", node)
- }
- }
-
- pub fn with_path<T>(&self, id: NodeId, f: |PathElems| -> T) -> T {
- self.with_path_next(id, None, f)
- }
-
- pub fn path_to_str(&self, id: NodeId) -> String {
- self.with_path(id, |path| path_to_str(path))
- }
-
- fn path_to_str_with_ident(&self, id: NodeId, i: Ident) -> String {
- self.with_path(id, |path| {
- path_to_str(path.chain(Some(PathName(i.name)).move_iter()))
- })
- }
-
- fn with_path_next<T>(&self, id: NodeId, next: LinkedPath, f: |PathElems| -> T) -> T {
- let parent = self.get_parent(id);
- let parent = match self.find_entry(id) {
- Some(EntryForeignItem(..)) | Some(EntryVariant(..)) => {
- // Anonymous extern items, enum variants and struct ctors
- // go in the parent scope.
- self.get_parent(parent)
- }
- // But tuple struct ctors don't have names, so use the path of its
- // parent, the struct item. Similarly with closure expressions.
- Some(EntryStructCtor(..)) | Some(EntryExpr(..)) => {
- return self.with_path_next(parent, next, f);
- }
- _ => parent
- };
- if parent == id {
- match self.find_entry(id) {
- Some(RootInlinedParent(data)) => {
- f(Values(data.path.iter()).chain(next))
- }
- _ => f(Values([].iter()).chain(next))
- }
- } else {
- self.with_path_next(parent, Some(&LinkedPathNode {
- node: self.get_path_elem(id),
- next: next
- }), f)
- }
- }
-
- pub fn with_attrs<T>(&self, id: NodeId, f: |Option<&[Attribute]>| -> T) -> T {
- let node = self.get(id);
- let attrs = match node {
- NodeItem(ref i) => Some(i.attrs.as_slice()),
- NodeForeignItem(ref fi) => Some(fi.attrs.as_slice()),
- NodeTraitMethod(ref tm) => match **tm {
- Required(ref type_m) => Some(type_m.attrs.as_slice()),
- Provided(ref m) => Some(m.attrs.as_slice())
- },
- NodeMethod(ref m) => Some(m.attrs.as_slice()),
- NodeVariant(ref v) => Some(v.node.attrs.as_slice()),
- // unit/tuple structs take the attributes straight from
- // the struct definition.
- // FIXME(eddyb) make this work again (requires access to the map).
- NodeStructCtor(_) => {
- return self.with_attrs(self.get_parent(id), f);
- }
- _ => None
- };
- f(attrs)
- }
-
- pub fn opt_span(&self, id: NodeId) -> Option<Span> {
- let sp = match self.find(id) {
- Some(NodeItem(item)) => item.span,
- Some(NodeForeignItem(foreign_item)) => foreign_item.span,
- Some(NodeTraitMethod(trait_method)) => {
- match *trait_method {
- Required(ref type_method) => type_method.span,
- Provided(ref method) => method.span,
- }
- }
- Some(NodeMethod(method)) => method.span,
- Some(NodeVariant(variant)) => variant.span,
- Some(NodeExpr(expr)) => expr.span,
- Some(NodeStmt(stmt)) => stmt.span,
- Some(NodeArg(pat)) | Some(NodeLocal(pat)) => pat.span,
- Some(NodePat(pat)) => pat.span,
- Some(NodeBlock(block)) => block.span,
- Some(NodeStructCtor(_)) => self.expect_item(self.get_parent(id)).span,
- _ => return None,
- };
- Some(sp)
- }
-
- pub fn span(&self, id: NodeId) -> Span {
- self.opt_span(id)
- .unwrap_or_else(|| fail!("AstMap.span: could not find span for id {}", id))
- }
-
- pub fn node_to_str(&self, id: NodeId) -> String {
- node_id_to_str(self, id)
- }
-}
-
-pub trait FoldOps {
- fn new_id(&self, id: NodeId) -> NodeId {
- id
- }
- fn new_span(&self, span: Span) -> Span {
- span
- }
-}
-
-pub struct Ctx<'a, F> {
- map: &'a Map,
- // The node in which we are currently mapping (an item or a method).
- // When equal to DUMMY_NODE_ID, the next mapped node becomes the parent.
- parent: NodeId,
- fold_ops: F
-}
-
-impl<'a, F> Ctx<'a, F> {
- fn insert(&self, id: NodeId, entry: MapEntry) {
- (*self.map.map.borrow_mut()).grow_set(id as uint, &NotPresent, entry);
- }
-}
-
-impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
- fn new_id(&mut self, id: NodeId) -> NodeId {
- let id = self.fold_ops.new_id(id);
- if self.parent == DUMMY_NODE_ID {
- self.parent = id;
- }
- id
- }
-
- fn new_span(&mut self, span: Span) -> Span {
- self.fold_ops.new_span(span)
- }
-
- fn fold_item(&mut self, i: Gc<Item>) -> SmallVector<Gc<Item>> {
- let parent = self.parent;
- self.parent = DUMMY_NODE_ID;
-
- let i = fold::noop_fold_item(&*i, self).expect_one("expected one item");
- assert_eq!(self.parent, i.id);
-
- match i.node {
- ItemImpl(_, _, _, ref ms) => {
- for &m in ms.iter() {
- self.insert(m.id, EntryMethod(self.parent, m));
- }
- }
- ItemEnum(ref enum_definition, _) => {
- for &v in enum_definition.variants.iter() {
- self.insert(v.node.id, EntryVariant(self.parent, v));
- }
- }
- ItemForeignMod(ref nm) => {
- for nitem in nm.items.iter() {
- self.insert(nitem.id, EntryForeignItem(self.parent,
- nitem.clone()));
- }
- }
- ItemStruct(ref struct_def, _) => {
- // If this is a tuple-like struct, register the constructor.
- match struct_def.ctor_id {
- Some(ctor_id) => {
- self.insert(ctor_id, EntryStructCtor(self.parent,
- struct_def.clone()));
- }
- None => {}
- }
- }
- ItemTrait(_, _, ref traits, ref methods) => {
- for t in traits.iter() {
- self.insert(t.ref_id, EntryItem(self.parent, i));
- }
-
- for tm in methods.iter() {
- match *tm {
- Required(ref m) => {
- self.insert(m.id, EntryTraitMethod(self.parent,
- box(GC) (*tm).clone()));
- }
- Provided(m) => {
- self.insert(m.id, EntryTraitMethod(self.parent,
- box(GC) Provided(m)));
- }
- }
- }
- }
- _ => {}
- }
-
- self.parent = parent;
- self.insert(i.id, EntryItem(self.parent, i));
-
- SmallVector::one(i)
- }
-
- fn fold_pat(&mut self, pat: Gc<Pat>) -> Gc<Pat> {
- let pat = fold::noop_fold_pat(pat, self);
- match pat.node {
- PatIdent(..) => {
- // Note: this is at least *potentially* a pattern...
- self.insert(pat.id, EntryLocal(self.parent, pat));
- }
- _ => {
- self.insert(pat.id, EntryPat(self.parent, pat));
- }
- }
-
- pat
- }
-
- fn fold_expr(&mut self, expr: Gc<Expr>) -> Gc<Expr> {
- let expr = fold::noop_fold_expr(expr, self);
-
- self.insert(expr.id, EntryExpr(self.parent, expr));
-
- expr
- }
-
- fn fold_stmt(&mut self, stmt: &Stmt) -> SmallVector<Gc<Stmt>> {
- let stmt = fold::noop_fold_stmt(stmt, self).expect_one("expected one statement");
- self.insert(ast_util::stmt_id(&*stmt), EntryStmt(self.parent, stmt));
- SmallVector::one(stmt)
- }
-
- fn fold_type_method(&mut self, m: &TypeMethod) -> TypeMethod {
- let parent = self.parent;
- self.parent = DUMMY_NODE_ID;
- let m = fold::noop_fold_type_method(m, self);
- assert_eq!(self.parent, m.id);
- self.parent = parent;
- m
- }
-
- fn fold_method(&mut self, m: Gc<Method>) -> Gc<Method> {
- let parent = self.parent;
- self.parent = DUMMY_NODE_ID;
- let m = fold::noop_fold_method(&*m, self);
- assert_eq!(self.parent, m.id);
- self.parent = parent;
- m
- }
-
- fn fold_fn_decl(&mut self, decl: &FnDecl) -> P<FnDecl> {
- let decl = fold::noop_fold_fn_decl(decl, self);
- for a in decl.inputs.iter() {
- self.insert(a.id, EntryArg(self.parent, a.pat));
- }
- decl
- }
-
- fn fold_block(&mut self, block: P<Block>) -> P<Block> {
- let block = fold::noop_fold_block(block, self);
- self.insert(block.id, EntryBlock(self.parent, block));
- block
- }
-
- fn fold_lifetime(&mut self, lifetime: &Lifetime) -> Lifetime {
- let lifetime = fold::noop_fold_lifetime(lifetime, self);
- self.insert(lifetime.id, EntryLifetime(self.parent, box(GC) lifetime));
- lifetime
- }
-}
-
-pub fn map_crate<F: FoldOps>(krate: Crate, fold_ops: F) -> (Crate, Map) {
- let map = Map { map: RefCell::new(Vec::new()) };
- let krate = {
- let mut cx = Ctx {
- map: &map,
- parent: CRATE_NODE_ID,
- fold_ops: fold_ops
- };
- cx.insert(CRATE_NODE_ID, RootCrate);
- cx.fold_crate(krate)
- };
-
- if log_enabled!(::log::DEBUG) {
- let map = map.map.borrow();
- // This only makes sense for ordered stores; note the
- // enumerate to count the number of entries.
- let (entries_less_1, _) = (*map).iter().filter(|&x| {
- match *x {
- NotPresent => false,
- _ => true
- }
- }).enumerate().last().expect("AST map was empty after folding?");
-
- let entries = entries_less_1 + 1;
- let vector_length = (*map).len();
- debug!("The AST map has {} entries with a maximum of {}: occupancy {:.1}%",
- entries, vector_length, (entries as f64 / vector_length as f64) * 100.);
- }
-
- (krate, map)
-}
-
-// Used for items loaded from external crate that are being inlined into this
-// crate. The `path` should be the path to the item but should not include
-// the item itself.
-pub fn map_decoded_item<F: FoldOps>(map: &Map,
- path: Vec<PathElem> ,
- fold_ops: F,
- fold: |&mut Ctx<F>| -> InlinedItem)
- -> InlinedItem {
- let mut cx = Ctx {
- map: map,
- parent: DUMMY_NODE_ID,
- fold_ops: fold_ops
- };
-
- // Generate a NodeId for the RootInlinedParent inserted below.
- cx.new_id(DUMMY_NODE_ID);
-
- // Methods get added to the AST map when their impl is visited. Since we
- // don't decode and instantiate the impl, but just the method, we have to
- // add it to the table now. Likewise with foreign items.
- let mut def_id = DefId { krate: LOCAL_CRATE, node: DUMMY_NODE_ID };
- let ii = fold(&mut cx);
- match ii {
- IIItem(_) => {}
- IIMethod(impl_did, is_provided, m) => {
- let entry = if is_provided {
- EntryTraitMethod(cx.parent, box(GC) Provided(m))
- } else {
- EntryMethod(cx.parent, m)
- };
- cx.insert(m.id, entry);
- def_id = impl_did;
- }
- IIForeign(i) => {
- cx.insert(i.id, EntryForeignItem(cx.parent, i));
- }
- }
-
- cx.insert(cx.parent, RootInlinedParent(P(InlinedParent {
- path: path,
- def_id: def_id
- })));
-
- ii
-}
-
-fn node_id_to_str(map: &Map, id: NodeId) -> String {
- match map.find(id) {
- Some(NodeItem(item)) => {
- let path_str = map.path_to_str_with_ident(id, item.ident);
- let item_str = match item.node {
- ItemStatic(..) => "static",
- ItemFn(..) => "fn",
- ItemMod(..) => "mod",
- ItemForeignMod(..) => "foreign mod",
- ItemTy(..) => "ty",
- ItemEnum(..) => "enum",
- ItemStruct(..) => "struct",
- ItemTrait(..) => "trait",
- ItemImpl(..) => "impl",
- ItemMac(..) => "macro"
- };
- format!("{} {} (id={})", item_str, path_str, id)
- }
- Some(NodeForeignItem(item)) => {
- let path_str = map.path_to_str_with_ident(id, item.ident);
- format!("foreign item {} (id={})", path_str, id)
- }
- Some(NodeMethod(m)) => {
- format!("method {} in {} (id={})",
- token::get_ident(m.ident),
- map.path_to_str(id), id)
- }
- Some(NodeTraitMethod(ref tm)) => {
- let m = ast_util::trait_method_to_ty_method(&**tm);
- format!("method {} in {} (id={})",
- token::get_ident(m.ident),
- map.path_to_str(id), id)
- }
- Some(NodeVariant(ref variant)) => {
- format!("variant {} in {} (id={})",
- token::get_ident(variant.node.name),
- map.path_to_str(id), id)
- }
- Some(NodeExpr(ref expr)) => {
- format!("expr {} (id={})", pprust::expr_to_str(&**expr), id)
- }
- Some(NodeStmt(ref stmt)) => {
- format!("stmt {} (id={})", pprust::stmt_to_str(&**stmt), id)
- }
- Some(NodeArg(ref pat)) => {
- format!("arg {} (id={})", pprust::pat_to_str(&**pat), id)
- }
- Some(NodeLocal(ref pat)) => {
- format!("local {} (id={})", pprust::pat_to_str(&**pat), id)
- }
- Some(NodePat(ref pat)) => {
- format!("pat {} (id={})", pprust::pat_to_str(&**pat), id)
- }
- Some(NodeBlock(ref block)) => {
- format!("block {} (id={})", pprust::block_to_str(&**block), id)
- }
- Some(NodeStructCtor(_)) => {
- format!("struct_ctor {} (id={})", map.path_to_str(id), id)
- }
- Some(NodeLifetime(ref l)) => {
- format!("lifetime {} (id={})",
- pprust::lifetime_to_str(&**l), id)
- }
- None => {
- format!("unknown node (id={})", id)
- }
- }
-}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! This module provides a simplified abstraction for working with
+//! code blocks identified by their integer node-id. In particular,
+//! it captures a common set of attributes that all "function-like
+//! things" (represented by `FnLike` instances) share. For example,
+//! all `FnLike` instances have a type signature (be it explicit or
+//! inferred). And all `FnLike` instances have a body, i.e. the code
+//! that is run when the function-like thing it represents is invoked.
+//!
+//! With the above abstraction in place, one can treat the program
+//! text as a collection of blocks of code (and most such blocks are
+//! nested within a uniquely determined `FnLike`), and users can ask
+//! for the `Code` associated with a particular NodeId.
+
+use abi;
+use ast::{P, Block, FnDecl, NodeId};
+use ast;
+use ast_map::{Node};
+use ast_map;
+use ast_util;
+use codemap::Span;
+use visit;
+
+/// An FnLikeNode is a Node that is like a fn, in that it has a decl
+/// and a body (as well as a NodeId, a span, etc).
+///
+/// More specifically, it is one of either:
+/// - A function item,
+/// - A closure expr (i.e. an ExprFnBlock or ExprProc), or
+/// - The default implementation for a trait method.
+///
+/// To construct one, use the `Code::from_node` function.
+pub struct FnLikeNode { node: ast_map::Node }
+
+/// MaybeFnLike wraps a method that indicates if an object
+/// corresponds to some FnLikeNode.
+pub trait MaybeFnLike { fn is_fn_like(&self) -> bool; }
+
+/// Components shared by fn-like things (fn items, methods, closures).
+pub struct FnParts<'a> {
+ pub decl: P<FnDecl>,
+ pub body: P<Block>,
+ pub kind: visit::FnKind<'a>,
+ pub span: Span,
+ pub id: NodeId,
+}
+
+impl MaybeFnLike for ast::Item {
+ fn is_fn_like(&self) -> bool {
+ match self.node { ast::ItemFn(..) => true, _ => false, }
+ }
+}
+
+impl MaybeFnLike for ast::TraitMethod {
+ fn is_fn_like(&self) -> bool {
+ match *self { ast::Provided(_) => true, _ => false, }
+ }
+}
+
+impl MaybeFnLike for ast::Expr {
+ fn is_fn_like(&self) -> bool {
+ match self.node {
+ ast::ExprFnBlock(..) | ast::ExprProc(..) => true,
+ _ => false,
+ }
+ }
+}
+
+/// Carries either an FnLikeNode or a Block, as these are the two
+/// constructs that correspond to "code" (as in, something from which
+/// we can construct a control-flow graph).
+pub enum Code {
+ FnLikeCode(FnLikeNode),
+ BlockCode(P<Block>),
+}
+
+impl Code {
+ pub fn id(&self) -> ast::NodeId {
+ match *self {
+ FnLikeCode(node) => node.id(),
+ BlockCode(block) => block.id,
+ }
+ }
+
+ /// Attempts to construct a Code from presumed FnLike or Block node input.
+ pub fn from_node(node: Node) -> Option<Code> {
+ fn new(node: Node) -> FnLikeNode { FnLikeNode { node: node } }
+ match node {
+ ast_map::NodeItem(item) if item.is_fn_like() =>
+ Some(FnLikeCode(new(node))),
+ ast_map::NodeTraitMethod(tm) if tm.is_fn_like() =>
+ Some(FnLikeCode(new(node))),
+ ast_map::NodeMethod(_) =>
+ Some(FnLikeCode(new(node))),
+ ast_map::NodeExpr(e) if e.is_fn_like() =>
+ Some(FnLikeCode(new(node))),
+ ast_map::NodeBlock(block) =>
+ Some(BlockCode(block)),
+ _ =>
+ None,
+ }
+ }
+}
+
+/// These are all the components one can extract from a fn item for
+/// use when implementing FnLikeNode operations.
+struct ItemFnParts<'a> {
+ ident: ast::Ident,
+ decl: P<ast::FnDecl>,
+ style: ast::FnStyle,
+ abi: abi::Abi,
+ generics: &'a ast::Generics,
+ body: P<Block>,
+ id: ast::NodeId,
+ span: Span
+}
+
+/// These are all the components one can extract from a closure expr
+/// for use when implementing FnLikeNode operations.
+struct ClosureParts {
+ decl: P<FnDecl>,
+ body: P<Block>,
+ id: NodeId,
+ span: Span
+}
+
+impl ClosureParts {
+ fn new(d: P<FnDecl>, b: P<Block>, id: NodeId, s: Span) -> ClosureParts {
+ ClosureParts { decl: d, body: b, id: id, span: s }
+ }
+}
+
+impl FnLikeNode {
+ pub fn to_fn_parts<'a>(&'a self) -> FnParts<'a> {
+ FnParts {
+ decl: self.decl(),
+ body: self.body(),
+ kind: self.kind(),
+ span: self.span(),
+ id: self.id(),
+ }
+ }
+
+ pub fn body<'a>(&'a self) -> P<Block> {
+ self.handle(|i: ItemFnParts| i.body,
+ |m: &'a ast::Method| ast_util::method_body(m),
+ |c: ClosureParts| c.body)
+ }
+
+ pub fn decl<'a>(&'a self) -> P<FnDecl> {
+ self.handle(|i: ItemFnParts| i.decl,
+ |m: &'a ast::Method| ast_util::method_fn_decl(m),
+ |c: ClosureParts| c.decl)
+ }
+
+ pub fn span<'a>(&'a self) -> Span {
+ self.handle(|i: ItemFnParts| i.span,
+ |m: &'a ast::Method| m.span,
+ |c: ClosureParts| c.span)
+ }
+
+ pub fn id<'a>(&'a self) -> NodeId {
+ self.handle(|i: ItemFnParts| i.id,
+ |m: &'a ast::Method| m.id,
+ |c: ClosureParts| c.id)
+ }
+
+ pub fn kind<'a>(&'a self) -> visit::FnKind<'a> {
+ let item = |p: ItemFnParts<'a>| -> visit::FnKind<'a> {
+ visit::FkItemFn(p.ident, p.generics, p.style, p.abi)
+ };
+ let closure = |_: ClosureParts| {
+ visit::FkFnBlock
+ };
+ let method = |m: &'a ast::Method| {
+ visit::FkMethod(ast_util::method_ident(m), ast_util::method_generics(m), m)
+ };
+ self.handle(item, method, closure)
+ }
+
+ fn handle<'a, A>(&'a self,
+ item_fn: |ItemFnParts<'a>| -> A,
+ method: |&'a ast::Method| -> A,
+ closure: |ClosureParts| -> A) -> A {
+ match self.node {
+ ast_map::NodeItem(ref i) => match i.node {
+ ast::ItemFn(decl, style, abi, ref generics, block) =>
+ item_fn(ItemFnParts{
+ ident: i.ident, decl: decl, style: style, body: block,
+ generics: generics, abi: abi, id: i.id, span: i.span
+ }),
+ _ => fail!("item FnLikeNode that is not fn-like"),
+ },
+ ast_map::NodeTraitMethod(ref t) => match **t {
+ ast::Provided(ref m) => method(&**m),
+ _ => fail!("trait method FnLikeNode that is not fn-like"),
+ },
+ ast_map::NodeMethod(ref m) => method(&**m),
+ ast_map::NodeExpr(ref e) => match e.node {
+ ast::ExprFnBlock(ref decl, ref block) =>
+ closure(ClosureParts::new(*decl, *block, e.id, e.span)),
+ ast::ExprProc(ref decl, ref block) =>
+ closure(ClosureParts::new(*decl, *block, e.id, e.span)),
+ _ => fail!("expr FnLikeNode that is not fn-like"),
+ },
+ _ => fail!("other FnLikeNode that is not fn-like"),
+ }
+ }
+}
--- /dev/null
+// Copyright 2012-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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use abi;
+use ast::*;
+use ast_util;
+use codemap::Span;
+use fold::Folder;
+use fold;
+use parse::token;
+use print::pprust;
+use util::small_vector::SmallVector;
+
+use std::cell::RefCell;
+use std::fmt;
+use std::gc::{Gc, GC};
+use std::iter;
+use std::slice;
+
+pub mod blocks;
+
+#[deriving(Clone, PartialEq)]
+pub enum PathElem {
+ PathMod(Name),
+ PathName(Name)
+}
+
+impl PathElem {
+ pub fn name(&self) -> Name {
+ match *self {
+ PathMod(name) | PathName(name) => name
+ }
+ }
+}
+
+impl fmt::Show for PathElem {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let slot = token::get_name(self.name());
+ write!(f, "{}", slot)
+ }
+}
+
+#[deriving(Clone)]
+struct LinkedPathNode<'a> {
+ node: PathElem,
+ next: LinkedPath<'a>,
+}
+
+type LinkedPath<'a> = Option<&'a LinkedPathNode<'a>>;
+
+impl<'a> Iterator<PathElem> for LinkedPath<'a> {
+ fn next(&mut self) -> Option<PathElem> {
+ match *self {
+ Some(node) => {
+ *self = node.next;
+ Some(node.node)
+ }
+ None => None
+ }
+ }
+}
+
+// HACK(eddyb) move this into libstd (value wrapper for slice::Items).
+#[deriving(Clone)]
+pub struct Values<'a, T>(pub slice::Items<'a, T>);
+
+impl<'a, T: Copy> Iterator<T> for Values<'a, T> {
+ fn next(&mut self) -> Option<T> {
+ let &Values(ref mut items) = self;
+ items.next().map(|&x| x)
+ }
+}
+
+/// The type of the iterator used by with_path.
+pub type PathElems<'a, 'b> = iter::Chain<Values<'a, PathElem>, LinkedPath<'b>>;
+
+pub fn path_to_string<PI: Iterator<PathElem>>(mut path: PI) -> String {
+ let itr = token::get_ident_interner();
+
+ path.fold(String::new(), |mut s, e| {
+ let e = itr.get(e.name());
+ if !s.is_empty() {
+ s.push_str("::");
+ }
+ s.push_str(e.as_slice());
+ s
+ }).to_string()
+}
+
+#[deriving(Clone)]
+pub enum Node {
+ NodeItem(Gc<Item>),
+ NodeForeignItem(Gc<ForeignItem>),
+ NodeTraitMethod(Gc<TraitMethod>),
+ NodeMethod(Gc<Method>),
+ NodeVariant(P<Variant>),
+ NodeExpr(Gc<Expr>),
+ NodeStmt(Gc<Stmt>),
+ NodeArg(Gc<Pat>),
+ NodeLocal(Gc<Pat>),
+ NodePat(Gc<Pat>),
+ NodeBlock(P<Block>),
+
+ /// NodeStructCtor represents a tuple struct.
+ NodeStructCtor(Gc<StructDef>),
+
+ NodeLifetime(Gc<Lifetime>),
+}
+
+/// Represents an entry and its parent Node ID
+/// The odd layout is to bring down the total size.
+#[deriving(Clone)]
+enum MapEntry {
+ /// Placeholder for holes in the map.
+ NotPresent,
+
+ /// All the node types, with a parent ID.
+ EntryItem(NodeId, Gc<Item>),
+ EntryForeignItem(NodeId, Gc<ForeignItem>),
+ EntryTraitMethod(NodeId, Gc<TraitMethod>),
+ EntryMethod(NodeId, Gc<Method>),
+ EntryVariant(NodeId, P<Variant>),
+ EntryExpr(NodeId, Gc<Expr>),
+ EntryStmt(NodeId, Gc<Stmt>),
+ EntryArg(NodeId, Gc<Pat>),
+ EntryLocal(NodeId, Gc<Pat>),
+ EntryPat(NodeId, Gc<Pat>),
+ EntryBlock(NodeId, P<Block>),
+ EntryStructCtor(NodeId, Gc<StructDef>),
+ EntryLifetime(NodeId, Gc<Lifetime>),
+
+ /// Roots for node trees.
+ RootCrate,
+ RootInlinedParent(P<InlinedParent>)
+}
+
+struct InlinedParent {
+ path: Vec<PathElem> ,
+ /// Required by NodeTraitMethod and NodeMethod.
+ def_id: DefId
+}
+
+impl MapEntry {
+ fn parent(&self) -> Option<NodeId> {
+ Some(match *self {
+ EntryItem(id, _) => id,
+ EntryForeignItem(id, _) => id,
+ EntryTraitMethod(id, _) => id,
+ EntryMethod(id, _) => id,
+ EntryVariant(id, _) => id,
+ EntryExpr(id, _) => id,
+ EntryStmt(id, _) => id,
+ EntryArg(id, _) => id,
+ EntryLocal(id, _) => id,
+ EntryPat(id, _) => id,
+ EntryBlock(id, _) => id,
+ EntryStructCtor(id, _) => id,
+ EntryLifetime(id, _) => id,
+ _ => return None
+ })
+ }
+
+ fn to_node(&self) -> Option<Node> {
+ Some(match *self {
+ EntryItem(_, p) => NodeItem(p),
+ EntryForeignItem(_, p) => NodeForeignItem(p),
+ EntryTraitMethod(_, p) => NodeTraitMethod(p),
+ EntryMethod(_, p) => NodeMethod(p),
+ EntryVariant(_, p) => NodeVariant(p),
+ EntryExpr(_, p) => NodeExpr(p),
+ EntryStmt(_, p) => NodeStmt(p),
+ EntryArg(_, p) => NodeArg(p),
+ EntryLocal(_, p) => NodeLocal(p),
+ EntryPat(_, p) => NodePat(p),
+ EntryBlock(_, p) => NodeBlock(p),
+ EntryStructCtor(_, p) => NodeStructCtor(p),
+ EntryLifetime(_, p) => NodeLifetime(p),
+ _ => return None
+ })
+ }
+}
+
+/// Represents a mapping from Node IDs to AST elements and their parent
+/// Node IDs
+pub struct Map {
+ /// NodeIds are sequential integers from 0, so we can be
+ /// super-compact by storing them in a vector. Not everything with
+ /// a NodeId is in the map, but empirically the occupancy is about
+ /// 75-80%, so there's not too much overhead (certainly less than
+ /// a hashmap, since they (at the time of writing) have a maximum
+ /// of 75% occupancy).
+ ///
+ /// Also, indexing is pretty quick when you've got a vector and
+ /// plain old integers.
+ map: RefCell<Vec<MapEntry> >
+}
+
+impl Map {
+ fn find_entry(&self, id: NodeId) -> Option<MapEntry> {
+ let map = self.map.borrow();
+ if map.len() > id as uint {
+ Some(*map.get(id as uint))
+ } else {
+ None
+ }
+ }
+
+ /// Retrieve the Node corresponding to `id`, failing if it cannot
+ /// be found.
+ pub fn get(&self, id: NodeId) -> Node {
+ match self.find(id) {
+ Some(node) => node,
+ None => fail!("couldn't find node id {} in the AST map", id)
+ }
+ }
+
+ /// Retrieve the Node corresponding to `id`, returning None if
+ /// cannot be found.
+ pub fn find(&self, id: NodeId) -> Option<Node> {
+ self.find_entry(id).and_then(|x| x.to_node())
+ }
+
+ /// Retrieve the parent NodeId for `id`, or `id` itself if no
+ /// parent is registered in this map.
+ pub fn get_parent(&self, id: NodeId) -> NodeId {
+ self.find_entry(id).and_then(|x| x.parent()).unwrap_or(id)
+ }
+
+ pub fn get_parent_did(&self, id: NodeId) -> DefId {
+ let parent = self.get_parent(id);
+ match self.find_entry(parent) {
+ Some(RootInlinedParent(data)) => data.def_id,
+ _ => ast_util::local_def(parent)
+ }
+ }
+
+ pub fn get_foreign_abi(&self, id: NodeId) -> abi::Abi {
+ let parent = self.get_parent(id);
+ let abi = match self.find_entry(parent) {
+ Some(EntryItem(_, i)) => match i.node {
+ ItemForeignMod(ref nm) => Some(nm.abi),
+ _ => None
+ },
+ /// Wrong but OK, because the only inlined foreign items are intrinsics.
+ Some(RootInlinedParent(_)) => Some(abi::RustIntrinsic),
+ _ => None
+ };
+ match abi {
+ Some(abi) => abi,
+ None => fail!("expected foreign mod or inlined parent, found {}",
+ self.node_to_string(parent))
+ }
+ }
+
+ pub fn get_foreign_vis(&self, id: NodeId) -> Visibility {
+ let vis = self.expect_foreign_item(id).vis;
+ match self.find(self.get_parent(id)) {
+ Some(NodeItem(i)) => vis.inherit_from(i.vis),
+ _ => vis
+ }
+ }
+
+ pub fn expect_item(&self, id: NodeId) -> Gc<Item> {
+ match self.find(id) {
+ Some(NodeItem(item)) => item,
+ _ => fail!("expected item, found {}", self.node_to_string(id))
+ }
+ }
+
+ pub fn expect_struct(&self, id: NodeId) -> Gc<StructDef> {
+ match self.find(id) {
+ Some(NodeItem(i)) => {
+ match i.node {
+ ItemStruct(struct_def, _) => struct_def,
+ _ => fail!("struct ID bound to non-struct")
+ }
+ }
+ Some(NodeVariant(ref variant)) => {
+ match (*variant).node.kind {
+ StructVariantKind(struct_def) => struct_def,
+ _ => fail!("struct ID bound to enum variant that isn't struct-like"),
+ }
+ }
+ _ => fail!(format!("expected struct, found {}", self.node_to_string(id))),
+ }
+ }
+
+ pub fn expect_variant(&self, id: NodeId) -> P<Variant> {
+ match self.find(id) {
+ Some(NodeVariant(variant)) => variant,
+ _ => fail!(format!("expected variant, found {}", self.node_to_string(id))),
+ }
+ }
+
+ pub fn expect_foreign_item(&self, id: NodeId) -> Gc<ForeignItem> {
+ match self.find(id) {
+ Some(NodeForeignItem(item)) => item,
+ _ => fail!("expected foreign item, found {}", self.node_to_string(id))
+ }
+ }
+
+ /// returns the name associated with the given NodeId's AST
+ pub fn get_path_elem(&self, id: NodeId) -> PathElem {
+ let node = self.get(id);
+ match node {
+ NodeItem(item) => {
+ match item.node {
+ ItemMod(_) | ItemForeignMod(_) => {
+ PathMod(item.ident.name)
+ }
+ _ => PathName(item.ident.name)
+ }
+ }
+ NodeForeignItem(i) => PathName(i.ident.name),
+ NodeMethod(m) => match m.node {
+ MethDecl(ident, _, _, _, _, _, _) => PathName(ident.name),
+ MethMac(_) => fail!("no path elem for {:?}", node)
+ },
+ NodeTraitMethod(tm) => match *tm {
+ Required(ref m) => PathName(m.ident.name),
+ Provided(m) => match m.node {
+ MethDecl(ident, _, _, _, _, _, _) => PathName(ident.name),
+ MethMac(_) => fail!("no path elem for {:?}", node),
+ }
+ },
+ NodeVariant(v) => PathName(v.node.name.name),
+ _ => fail!("no path elem for {:?}", node)
+ }
+ }
+
+ pub fn with_path<T>(&self, id: NodeId, f: |PathElems| -> T) -> T {
+ self.with_path_next(id, None, f)
+ }
+
+ pub fn path_to_string(&self, id: NodeId) -> String {
+ self.with_path(id, |path| path_to_string(path))
+ }
+
+ fn path_to_str_with_ident(&self, id: NodeId, i: Ident) -> String {
+ self.with_path(id, |path| {
+ path_to_string(path.chain(Some(PathName(i.name)).move_iter()))
+ })
+ }
+
+ fn with_path_next<T>(&self, id: NodeId, next: LinkedPath, f: |PathElems| -> T) -> T {
+ let parent = self.get_parent(id);
+ let parent = match self.find_entry(id) {
+ Some(EntryForeignItem(..)) | Some(EntryVariant(..)) => {
+ // Anonymous extern items, enum variants and struct ctors
+ // go in the parent scope.
+ self.get_parent(parent)
+ }
+ // But tuple struct ctors don't have names, so use the path of its
+ // parent, the struct item. Similarly with closure expressions.
+ Some(EntryStructCtor(..)) | Some(EntryExpr(..)) => {
+ return self.with_path_next(parent, next, f);
+ }
+ _ => parent
+ };
+ if parent == id {
+ match self.find_entry(id) {
+ Some(RootInlinedParent(data)) => {
+ f(Values(data.path.iter()).chain(next))
+ }
+ _ => f(Values([].iter()).chain(next))
+ }
+ } else {
+ self.with_path_next(parent, Some(&LinkedPathNode {
+ node: self.get_path_elem(id),
+ next: next
+ }), f)
+ }
+ }
+
+ /// Given a node ID and a closure, apply the closure to the array
+ /// of attributes associated with the AST corresponding to the Node ID
+ pub fn with_attrs<T>(&self, id: NodeId, f: |Option<&[Attribute]>| -> T) -> T {
+ let node = self.get(id);
+ let attrs = match node {
+ NodeItem(ref i) => Some(i.attrs.as_slice()),
+ NodeForeignItem(ref fi) => Some(fi.attrs.as_slice()),
+ NodeTraitMethod(ref tm) => match **tm {
+ Required(ref type_m) => Some(type_m.attrs.as_slice()),
+ Provided(ref m) => Some(m.attrs.as_slice())
+ },
+ NodeMethod(ref m) => Some(m.attrs.as_slice()),
+ NodeVariant(ref v) => Some(v.node.attrs.as_slice()),
+ // unit/tuple structs take the attributes straight from
+ // the struct definition.
+ // FIXME(eddyb) make this work again (requires access to the map).
+ NodeStructCtor(_) => {
+ return self.with_attrs(self.get_parent(id), f);
+ }
+ _ => None
+ };
+ f(attrs)
+ }
+
+ pub fn opt_span(&self, id: NodeId) -> Option<Span> {
+ let sp = match self.find(id) {
+ Some(NodeItem(item)) => item.span,
+ Some(NodeForeignItem(foreign_item)) => foreign_item.span,
+ Some(NodeTraitMethod(trait_method)) => {
+ match *trait_method {
+ Required(ref type_method) => type_method.span,
+ Provided(ref method) => method.span,
+ }
+ }
+ Some(NodeMethod(method)) => method.span,
+ Some(NodeVariant(variant)) => variant.span,
+ Some(NodeExpr(expr)) => expr.span,
+ Some(NodeStmt(stmt)) => stmt.span,
+ Some(NodeArg(pat)) | Some(NodeLocal(pat)) => pat.span,
+ Some(NodePat(pat)) => pat.span,
+ Some(NodeBlock(block)) => block.span,
+ Some(NodeStructCtor(_)) => self.expect_item(self.get_parent(id)).span,
+ _ => return None,
+ };
+ Some(sp)
+ }
+
+ pub fn span(&self, id: NodeId) -> Span {
+ self.opt_span(id)
+ .unwrap_or_else(|| fail!("AstMap.span: could not find span for id {}", id))
+ }
+
+ pub fn node_to_string(&self, id: NodeId) -> String {
+ node_id_to_string(self, id)
+ }
+}
+
+pub trait FoldOps {
+ fn new_id(&self, id: NodeId) -> NodeId {
+ id
+ }
+ fn new_span(&self, span: Span) -> Span {
+ span
+ }
+}
+
+/// A Folder that walks over an AST and constructs a Node ID Map. Its
+/// fold_ops argument has the opportunity to replace Node IDs and spans.
+pub struct Ctx<'a, F> {
+ map: &'a Map,
+ /// The node in which we are currently mapping (an item or a method).
+ /// When equal to DUMMY_NODE_ID, the next mapped node becomes the parent.
+ parent: NodeId,
+ fold_ops: F
+}
+
+impl<'a, F> Ctx<'a, F> {
+ fn insert(&self, id: NodeId, entry: MapEntry) {
+ (*self.map.map.borrow_mut()).grow_set(id as uint, &NotPresent, entry);
+ }
+}
+
+impl<'a, F: FoldOps> Folder for Ctx<'a, F> {
+ fn new_id(&mut self, id: NodeId) -> NodeId {
+ let id = self.fold_ops.new_id(id);
+ if self.parent == DUMMY_NODE_ID {
+ self.parent = id;
+ }
+ id
+ }
+
+ fn new_span(&mut self, span: Span) -> Span {
+ self.fold_ops.new_span(span)
+ }
+
+ fn fold_item(&mut self, i: Gc<Item>) -> SmallVector<Gc<Item>> {
+ let parent = self.parent;
+ self.parent = DUMMY_NODE_ID;
+
+ let i = fold::noop_fold_item(&*i, self).expect_one("expected one item");
+ assert_eq!(self.parent, i.id);
+
+ match i.node {
+ ItemImpl(_, _, _, ref ms) => {
+ for &m in ms.iter() {
+ self.insert(m.id, EntryMethod(self.parent, m));
+ }
+ }
+ ItemEnum(ref enum_definition, _) => {
+ for &v in enum_definition.variants.iter() {
+ self.insert(v.node.id, EntryVariant(self.parent, v));
+ }
+ }
+ ItemForeignMod(ref nm) => {
+ for nitem in nm.items.iter() {
+ self.insert(nitem.id, EntryForeignItem(self.parent,
+ nitem.clone()));
+ }
+ }
+ ItemStruct(ref struct_def, _) => {
+ // If this is a tuple-like struct, register the constructor.
+ match struct_def.ctor_id {
+ Some(ctor_id) => {
+ self.insert(ctor_id, EntryStructCtor(self.parent,
+ struct_def.clone()));
+ }
+ None => {}
+ }
+ }
+ ItemTrait(_, _, ref traits, ref methods) => {
+ for t in traits.iter() {
+ self.insert(t.ref_id, EntryItem(self.parent, i));
+ }
+
+ for tm in methods.iter() {
+ match *tm {
+ Required(ref m) => {
+ self.insert(m.id, EntryTraitMethod(self.parent,
+ box(GC) (*tm).clone()));
+ }
+ Provided(m) => {
+ self.insert(m.id, EntryTraitMethod(self.parent,
+ box(GC) Provided(m)));
+ }
+ }
+ }
+ }
+ _ => {}
+ }
+
+ self.parent = parent;
+ self.insert(i.id, EntryItem(self.parent, i));
+
+ SmallVector::one(i)
+ }
+
+ fn fold_pat(&mut self, pat: Gc<Pat>) -> Gc<Pat> {
+ let pat = fold::noop_fold_pat(pat, self);
+ match pat.node {
+ PatIdent(..) => {
+ // Note: this is at least *potentially* a pattern...
+ self.insert(pat.id, EntryLocal(self.parent, pat));
+ }
+ _ => {
+ self.insert(pat.id, EntryPat(self.parent, pat));
+ }
+ }
+
+ pat
+ }
+
+ fn fold_expr(&mut self, expr: Gc<Expr>) -> Gc<Expr> {
+ let expr = fold::noop_fold_expr(expr, self);
+
+ self.insert(expr.id, EntryExpr(self.parent, expr));
+
+ expr
+ }
+
+ fn fold_stmt(&mut self, stmt: &Stmt) -> SmallVector<Gc<Stmt>> {
+ let stmt = fold::noop_fold_stmt(stmt, self).expect_one("expected one statement");
+ self.insert(ast_util::stmt_id(&*stmt), EntryStmt(self.parent, stmt));
+ SmallVector::one(stmt)
+ }
+
+ fn fold_type_method(&mut self, m: &TypeMethod) -> TypeMethod {
+ let parent = self.parent;
+ self.parent = DUMMY_NODE_ID;
+ let m = fold::noop_fold_type_method(m, self);
+ assert_eq!(self.parent, m.id);
+ self.parent = parent;
+ m
+ }
+
+ fn fold_method(&mut self, m: Gc<Method>) -> SmallVector<Gc<Method>> {
+ let parent = self.parent;
+ self.parent = DUMMY_NODE_ID;
+ let m = fold::noop_fold_method(&*m, self).expect_one(
+ "noop_fold_method must produce exactly one method");
+ assert_eq!(self.parent, m.id);
+ self.parent = parent;
+ SmallVector::one(m)
+ }
+
+ fn fold_fn_decl(&mut self, decl: &FnDecl) -> P<FnDecl> {
+ let decl = fold::noop_fold_fn_decl(decl, self);
+ for a in decl.inputs.iter() {
+ self.insert(a.id, EntryArg(self.parent, a.pat));
+ }
+ decl
+ }
+
+ fn fold_block(&mut self, block: P<Block>) -> P<Block> {
+ let block = fold::noop_fold_block(block, self);
+ self.insert(block.id, EntryBlock(self.parent, block));
+ block
+ }
+
+ fn fold_lifetime(&mut self, lifetime: &Lifetime) -> Lifetime {
+ let lifetime = fold::noop_fold_lifetime(lifetime, self);
+ self.insert(lifetime.id, EntryLifetime(self.parent, box(GC) lifetime));
+ lifetime
+ }
+
+ fn fold_mac(&mut self, mac: &Mac) -> Mac {
+ fold::fold_mac(mac, self)
+ }
+}
+
+pub fn map_crate<F: FoldOps>(krate: Crate, fold_ops: F) -> (Crate, Map) {
+ let map = Map { map: RefCell::new(Vec::new()) };
+ let krate = {
+ let mut cx = Ctx {
+ map: &map,
+ parent: CRATE_NODE_ID,
+ fold_ops: fold_ops
+ };
+ cx.insert(CRATE_NODE_ID, RootCrate);
+ cx.fold_crate(krate)
+ };
+
+ if log_enabled!(::log::DEBUG) {
+ let map = map.map.borrow();
+ // This only makes sense for ordered stores; note the
+ // enumerate to count the number of entries.
+ let (entries_less_1, _) = (*map).iter().filter(|&x| {
+ match *x {
+ NotPresent => false,
+ _ => true
+ }
+ }).enumerate().last().expect("AST map was empty after folding?");
+
+ let entries = entries_less_1 + 1;
+ let vector_length = (*map).len();
+ debug!("The AST map has {} entries with a maximum of {}: occupancy {:.1}%",
+ entries, vector_length, (entries as f64 / vector_length as f64) * 100.);
+ }
+
+ (krate, map)
+}
+
+/// Used for items loaded from external crate that are being inlined into this
+/// crate. The `path` should be the path to the item but should not include
+/// the item itself.
+pub fn map_decoded_item<F: FoldOps>(map: &Map,
+ path: Vec<PathElem> ,
+ fold_ops: F,
+ fold: |&mut Ctx<F>| -> InlinedItem)
+ -> InlinedItem {
+ let mut cx = Ctx {
+ map: map,
+ parent: DUMMY_NODE_ID,
+ fold_ops: fold_ops
+ };
+
+ // Generate a NodeId for the RootInlinedParent inserted below.
+ cx.new_id(DUMMY_NODE_ID);
+
+ // Methods get added to the AST map when their impl is visited. Since we
+ // don't decode and instantiate the impl, but just the method, we have to
+ // add it to the table now. Likewise with foreign items.
+ let mut def_id = DefId { krate: LOCAL_CRATE, node: DUMMY_NODE_ID };
+ let ii = fold(&mut cx);
+ match ii {
+ IIItem(_) => {}
+ IIMethod(impl_did, is_provided, m) => {
+ let entry = if is_provided {
+ EntryTraitMethod(cx.parent, box(GC) Provided(m))
+ } else {
+ EntryMethod(cx.parent, m)
+ };
+ cx.insert(m.id, entry);
+ def_id = impl_did;
+ }
+ IIForeign(i) => {
+ cx.insert(i.id, EntryForeignItem(cx.parent, i));
+ }
+ }
+
+ cx.insert(cx.parent, RootInlinedParent(P(InlinedParent {
+ path: path,
+ def_id: def_id
+ })));
+
+ ii
+}
+
+fn node_id_to_string(map: &Map, id: NodeId) -> String {
+ match map.find(id) {
+ Some(NodeItem(item)) => {
+ let path_str = map.path_to_str_with_ident(id, item.ident);
+ let item_str = match item.node {
+ ItemStatic(..) => "static",
+ ItemFn(..) => "fn",
+ ItemMod(..) => "mod",
+ ItemForeignMod(..) => "foreign mod",
+ ItemTy(..) => "ty",
+ ItemEnum(..) => "enum",
+ ItemStruct(..) => "struct",
+ ItemTrait(..) => "trait",
+ ItemImpl(..) => "impl",
+ ItemMac(..) => "macro"
+ };
+ format!("{} {} (id={})", item_str, path_str, id)
+ }
+ Some(NodeForeignItem(item)) => {
+ let path_str = map.path_to_str_with_ident(id, item.ident);
+ format!("foreign item {} (id={})", path_str, id)
+ }
+ Some(NodeMethod(m)) => match m.node {
+ MethDecl(ident, _, _, _, _, _, _) =>
+ format!("method {} in {} (id={})",
+ token::get_ident(ident),
+ map.path_to_string(id), id),
+ MethMac(ref mac) =>
+ format!("method macro {} (id={})",
+ pprust::mac_to_string(mac), id)
+ },
+ Some(NodeTraitMethod(ref tm)) => {
+ let m = ast_util::trait_method_to_ty_method(&**tm);
+ format!("method {} in {} (id={})",
+ token::get_ident(m.ident),
+ map.path_to_string(id), id)
+ }
+ Some(NodeVariant(ref variant)) => {
+ format!("variant {} in {} (id={})",
+ token::get_ident(variant.node.name),
+ map.path_to_string(id), id)
+ }
+ Some(NodeExpr(ref expr)) => {
+ format!("expr {} (id={})", pprust::expr_to_string(&**expr), id)
+ }
+ Some(NodeStmt(ref stmt)) => {
+ format!("stmt {} (id={})", pprust::stmt_to_string(&**stmt), id)
+ }
+ Some(NodeArg(ref pat)) => {
+ format!("arg {} (id={})", pprust::pat_to_string(&**pat), id)
+ }
+ Some(NodeLocal(ref pat)) => {
+ format!("local {} (id={})", pprust::pat_to_string(&**pat), id)
+ }
+ Some(NodePat(ref pat)) => {
+ format!("pat {} (id={})", pprust::pat_to_string(&**pat), id)
+ }
+ Some(NodeBlock(ref block)) => {
+ format!("block {} (id={})", pprust::block_to_string(&**block), id)
+ }
+ Some(NodeStructCtor(_)) => {
+ format!("struct_ctor {} (id={})", map.path_to_string(id), id)
+ }
+ Some(NodeLifetime(ref l)) => {
+ format!("lifetime {} (id={})",
+ pprust::lifetime_to_string(&**l), id)
+ }
+ None => {
+ format!("unknown node (id={})", id)
+ }
+ }
+}
}
}
-pub fn binop_to_str(op: BinOp) -> &'static str {
+pub fn binop_to_string(op: BinOp) -> &'static str {
match op {
BiAdd => "+",
BiSub => "-",
}
}
-pub fn unop_to_str(op: UnOp) -> &'static str {
+pub fn unop_to_string(op: UnOp) -> &'static str {
match op {
UnBox => "box(GC) ",
UnUniq => "box() ",
return match e.node { ExprPath(_) => true, _ => false };
}
-// Get a string representation of a signed int type, with its value.
-// We want to avoid "45int" and "-3int" in favor of "45" and "-3"
-pub fn int_ty_to_str(t: IntTy, val: Option<i64>) -> String {
+/// Get a string representation of a signed int type, with its value.
+/// We want to avoid "45int" and "-3int" in favor of "45" and "-3"
+pub fn int_ty_to_string(t: IntTy, val: Option<i64>) -> String {
let s = match t {
TyI if val.is_some() => "i",
TyI => "int",
}
}
-// Get a string representation of an unsigned int type, with its value.
-// We want to avoid "42uint" in favor of "42u"
-pub fn uint_ty_to_str(t: UintTy, val: Option<u64>) -> String {
+/// Get a string representation of an unsigned int type, with its value.
+/// We want to avoid "42uint" in favor of "42u"
+pub fn uint_ty_to_string(t: UintTy, val: Option<u64>) -> String {
let s = match t {
TyU if val.is_some() => "u",
TyU => "uint",
}
}
-pub fn float_ty_to_str(t: FloatTy) -> String {
+pub fn float_ty_to_string(t: FloatTy) -> String {
match t {
TyF32 => "f32".to_string(),
TyF64 => "f64".to_string(),
/// listed as `__extensions__::method_name::hash`, with no indication
/// of the type).
pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
- let mut pretty = pprust::ty_to_str(ty);
+ let mut pretty = pprust::ty_to_string(ty);
match *trait_ref {
Some(ref trait_ref) => {
pretty.push_char('.');
- pretty.push_str(pprust::path_to_str(&trait_ref.path).as_slice());
+ pretty.push_str(pprust::path_to_string(&trait_ref.path).as_slice());
}
None => {}
}
token::gensym_ident(pretty.as_slice())
}
-pub fn public_methods(ms: Vec<Gc<Method>> ) -> Vec<Gc<Method>> {
- ms.move_iter().filter(|m| {
- match m.vis {
- Public => true,
- _ => false
- }
- }).collect()
-}
-
-// extract a TypeMethod from a TraitMethod. if the TraitMethod is
-// a default, pull out the useful fields to make a TypeMethod
+/// extract a TypeMethod from a TraitMethod. if the TraitMethod is
+/// a default, pull out the useful fields to make a TypeMethod
+//
+// NB: to be used only after expansion is complete, and macros are gone.
pub fn trait_method_to_ty_method(method: &TraitMethod) -> TypeMethod {
match *method {
Required(ref m) => (*m).clone(),
- Provided(ref m) => {
- TypeMethod {
- ident: m.ident,
- attrs: m.attrs.clone(),
- fn_style: m.fn_style,
- decl: m.decl,
- generics: m.generics.clone(),
- explicit_self: m.explicit_self,
- id: m.id,
- span: m.span,
- vis: m.vis,
+ Provided(m) => {
+ match m.node {
+ MethDecl(ident, ref generics, explicit_self, fn_style, decl, _, vis) => {
+ TypeMethod {
+ ident: ident,
+ attrs: m.attrs.clone(),
+ fn_style: fn_style,
+ decl: decl,
+ generics: generics.clone(),
+ explicit_self: explicit_self,
+ id: m.id,
+ span: m.span,
+ vis: vis,
+ }
+ },
+ MethMac(_) => fail!("expected non-macro method declaration")
}
+
}
}
}
fn visit_id(&self, node_id: NodeId);
}
+/// A visitor that applies its operation to all of the node IDs
+/// in a visitable thing.
+
pub struct IdVisitor<'a, O> {
pub operation: &'a O,
pub pass_through_items: bool,
match pat.node {
PatIdent(_, _, Some(ref p)) => walk_pat(&**p, it),
PatStruct(_, ref fields, _) => {
- fields.iter().advance(|f| walk_pat(&*f.pat, |p| it(p)))
+ fields.iter().all(|field| walk_pat(&*field.pat, |p| it(p)))
}
PatEnum(_, Some(ref s)) | PatTup(ref s) => {
- s.iter().advance(|p| walk_pat(&**p, |p| it(p)))
+ s.iter().all(|p| walk_pat(&**p, |p| it(p)))
}
PatBox(ref s) | PatRegion(ref s) => {
walk_pat(&**s, it)
}
PatVec(ref before, ref slice, ref after) => {
- before.iter().advance(|p| walk_pat(&**p, |p| it(p))) &&
- slice.iter().advance(|p| walk_pat(&**p, |p| it(p))) &&
- after.iter().advance(|p| walk_pat(&**p, |p| it(p)))
+ before.iter().all(|p| walk_pat(&**p, |p| it(p))) &&
+ slice.iter().all(|p| walk_pat(&**p, |p| it(p))) &&
+ after.iter().all(|p| walk_pat(&**p, |p| it(p)))
}
PatMac(_) => fail!("attempted to analyze unexpanded pattern"),
PatWild | PatWildMulti | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) |
}
}
-// Returns true if this literal is a string and false otherwise.
+/// Returns true if this literal is a string and false otherwise.
pub fn lit_is_str(lit: Gc<Lit>) -> bool {
match lit.node {
LitStr(..) => true,
inline == InlineNever || inline == InlineNone
}
+
+/// Macro invocations are guaranteed not to occur after expansion is complete.
+/// extracting fields of a method requires a dynamic check to make sure that it's
+/// not a macro invocation, though this check is guaranteed to succeed, assuming
+/// that the invocations are indeed gone.
+macro_rules! method_field_extractor {
+ ($fn_name:ident, $field_ty:ty, $field_pat:pat, $result:ident) => {
+ /// Returns the ident of a Method. To be used after expansion is complete
+ pub fn $fn_name<'a>(method: &'a ast::Method) -> $field_ty {
+ match method.node {
+ $field_pat => $result,
+ MethMac(_) => {
+ fail!("expected an AST without macro invocations");
+ }
+ }
+ }
+ }
+}
+
+// Note: this is unhygienic in the lifetime 'a. In order to fix this, we'd have to
+// add :lifetime as a macro argument type, so that the 'a could be supplied by the macro
+// invocation.
+pub method_field_extractor!(method_ident,ast::Ident,MethDecl(ident,_,_,_,_,_,_),ident)
+pub method_field_extractor!(method_generics,&'a ast::Generics,
+ MethDecl(_,ref generics,_,_,_,_,_),generics)
+pub method_field_extractor!(method_explicit_self,&'a ast::ExplicitSelf,
+ MethDecl(_,_,ref explicit_self,_,_,_,_),explicit_self)
+pub method_field_extractor!(method_fn_style,ast::FnStyle,MethDecl(_,_,_,fn_style,_,_,_),fn_style)
+pub method_field_extractor!(method_fn_decl,P<ast::FnDecl>,MethDecl(_,_,_,_,decl,_,_),decl)
+pub method_field_extractor!(method_body,P<ast::Block>,MethDecl(_,_,_,_,_,body,_),body)
+pub method_field_extractor!(method_vis,ast::Visibility,MethDecl(_,_,_,_,_,_,vis),vis)
+
#[cfg(test)]
mod test {
use ast::*;
#[test] fn idents_name_eq_test() {
assert!(segments_name_eq(
- [Ident{name:3,ctxt:4}, Ident{name:78,ctxt:82}]
+ [Ident{name:Name(3),ctxt:4}, Ident{name:Name(78),ctxt:82}]
.iter().map(ident_to_segment).collect::<Vec<PathSegment>>().as_slice(),
- [Ident{name:3,ctxt:104}, Ident{name:78,ctxt:182}]
+ [Ident{name:Name(3),ctxt:104}, Ident{name:Name(78),ctxt:182}]
.iter().map(ident_to_segment).collect::<Vec<PathSegment>>().as_slice()));
assert!(!segments_name_eq(
- [Ident{name:3,ctxt:4}, Ident{name:78,ctxt:82}]
+ [Ident{name:Name(3),ctxt:4}, Ident{name:Name(78),ctxt:82}]
.iter().map(ident_to_segment).collect::<Vec<PathSegment>>().as_slice(),
- [Ident{name:3,ctxt:104}, Ident{name:77,ctxt:182}]
+ [Ident{name:Name(3),ctxt:104}, Ident{name:Name(77),ctxt:182}]
.iter().map(ident_to_segment).collect::<Vec<PathSegment>>().as_slice()));
}
}
+
use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
use parse::token::InternedString;
use parse::token;
-use crateid::CrateId;
use std::collections::HashSet;
use std::collections::BitvSet;
/// #[foo="bar"] and #[foo(bar)]
fn name(&self) -> InternedString;
- /**
- * Gets the string value if self is a MetaNameValue variant
- * containing a string, otherwise None.
- */
+ /// Gets the string value if self is a MetaNameValue variant
+ /// containing a string, otherwise None.
fn value_str(&self) -> Option<InternedString>;
/// Gets a list of inner meta items from a list MetaItem type.
fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<MetaItem>]>;
}).collect()
}
-pub fn find_crateid(attrs: &[Attribute]) -> Option<CrateId> {
- match first_attr_value_str_by_name(attrs, "crate_id") {
- None => None,
- Some(id) => from_str::<CrateId>(id.get()),
- }
+pub fn find_crate_name(attrs: &[Attribute]) -> Option<InternedString> {
+ first_attr_value_str_by_name(attrs, "crate_name")
}
#[deriving(PartialEq)]
}
-/**
- * Fold this over attributes to parse #[repr(...)] forms.
- *
- * Valid repr contents: any of the primitive integral type names (see
- * `int_type_of_word`, below) to specify the discriminant type; and `C`, to use
- * the same discriminant size that the corresponding C enum would. These are
- * not allowed on univariant or zero-variant enums, which have no discriminant.
- *
- * If a discriminant type is so specified, then the discriminant will be
- * present (before fields, if any) with that type; reprensentation
- * optimizations which would remove it will not be done.
- */
+/// Fold this over attributes to parse #[repr(...)] forms.
+///
+/// Valid repr contents: any of the primitive integral type names (see
+/// `int_type_of_word`, below) to specify the discriminant type; and `C`, to use
+/// the same discriminant size that the corresponding C enum would. These are
+/// not allowed on univariant or zero-variant enums, which have no discriminant.
+///
+/// If a discriminant type is so specified, then the discriminant will be
+/// present (before fields, if any) with that type; reprensentation
+/// optimizations which would remove it will not be done.
pub fn find_repr_attr(diagnostic: &SpanHandler, attr: &Attribute, acc: ReprAttr)
-> ReprAttr {
let mut acc = acc;
pub static DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_info: None };
-#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub struct Spanned<T> {
pub node: T,
pub span: Span,
}
impl FileMap {
- // EFFECT: register a start-of-line offset in the
- // table of line-beginnings.
- // UNCHECKED INVARIANT: these offsets must be added in the right
- // order and must be in the right places; there is shared knowledge
- // about what ends a line between this file and parse.rs
- // WARNING: pos param here is the offset relative to start of CodeMap,
- // and CodeMap will append a newline when adding a filemap without a newline at the end,
- // so the safe way to call this is with value calculated as
- // filemap.start_pos + newline_offset_relative_to_the_start_of_filemap.
+ /// EFFECT: register a start-of-line offset in the
+ /// table of line-beginnings.
+ /// UNCHECKED INVARIANT: these offsets must be added in the right
+ /// order and must be in the right places; there is shared knowledge
+ /// about what ends a line between this file and parse.rs
+ /// WARNING: pos param here is the offset relative to start of CodeMap,
+ /// and CodeMap will append a newline when adding a filemap without a newline at the end,
+ /// so the safe way to call this is with value calculated as
+ /// filemap.start_pos + newline_offset_relative_to_the_start_of_filemap.
pub fn next_line(&self, pos: BytePos) {
// the new charpos must be > the last one (or it's the first one).
let mut lines = self.lines.borrow_mut();;
lines.push(pos);
}
- // get a line from the list of pre-computed line-beginnings
+ /// get a line from the list of pre-computed line-beginnings
pub fn get_line(&self, line: int) -> String {
let mut lines = self.lines.borrow_mut();
let begin: BytePos = *lines.get(line as uint) - self.start_pos;
}
}
- pub fn span_to_str(&self, sp: Span) -> String {
+ pub fn span_to_string(&self, sp: Span) -> String {
if self.files.borrow().len() == 0 && sp == DUMMY_SP {
return "no-location".to_string();
}
FileMapAndBytePos {fm: fm, pos: offset}
}
- // Converts an absolute BytePos to a CharPos relative to the filemap and above.
+ /// Converts an absolute BytePos to a CharPos relative to the filemap and above.
pub fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos {
- debug!("codemap: converting {:?} to char pos", bpos);
let idx = self.lookup_filemap_idx(bpos);
let files = self.files.borrow();
let map = files.get(idx);
let mut total_extra_bytes = 0;
for mbc in map.multibyte_chars.borrow().iter() {
- debug!("codemap: {:?}-byte char at {:?}", mbc.bytes, mbc.pos);
+ debug!("{}-byte char at {}", mbc.bytes, mbc.pos);
if mbc.pos < bpos {
// every character is at least one byte, so we only
// count the actual extra bytes.
let chpos = self.bytepos_to_file_charpos(pos);
let linebpos = *f.lines.borrow().get(a);
let linechpos = self.bytepos_to_file_charpos(linebpos);
- debug!("codemap: byte pos {:?} is on the line at byte pos {:?}",
+ debug!("byte pos {} is on the line at byte pos {}",
pos, linebpos);
- debug!("codemap: char pos {:?} is on the line at char pos {:?}",
+ debug!("char pos {} is on the line at char pos {}",
chpos, linechpos);
- debug!("codemap: byte is on line: {:?}", line);
+ debug!("byte is on line: {}", line);
assert!(chpos >= linechpos);
Loc {
file: f,
// Test span_to_str for a span ending at the end of filemap
let cm = init_code_map();
let span = Span {lo: BytePos(12), hi: BytePos(23), expn_info: None};
- let sstr = cm.span_to_str(span);
+ let sstr = cm.span_to_string(span);
assert_eq!(sstr, "blork.rs:2:1: 2:12".to_string());
}
use codemap::{Pos, Span};
use codemap;
+use diagnostics;
use std::cell::{RefCell, Cell};
use std::fmt;
use term::WriterWrapper;
use term;
-// maximum number of lines we will print for each error; arbitrary.
+/// maximum number of lines we will print for each error; arbitrary.
static MAX_LINES: uint = 6u;
#[deriving(Clone)]
pub trait Emitter {
fn emit(&mut self, cmsp: Option<(&codemap::CodeMap, Span)>,
- msg: &str, lvl: Level);
+ msg: &str, code: Option<&str>, lvl: Level);
fn custom_emit(&mut self, cm: &codemap::CodeMap,
sp: RenderSpan, msg: &str, lvl: Level);
}
/// or `.span_bug` rather than a failed assertion, etc.
pub struct ExplicitBug;
-// a span-handler is like a handler but also
-// accepts span information for source-location
-// reporting.
+/// A span-handler is like a handler but also
+/// accepts span information for source-location
+/// reporting.
pub struct SpanHandler {
pub handler: Handler,
pub cm: codemap::CodeMap,
self.handler.emit(Some((&self.cm, sp)), msg, Error);
self.handler.bump_err_count();
}
+ pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
+ self.handler.emit_with_code(Some((&self.cm, sp)), msg, code, Error);
+ self.handler.bump_err_count();
+ }
pub fn span_warn(&self, sp: Span, msg: &str) {
self.handler.emit(Some((&self.cm, sp)), msg, Warning);
}
}
}
-// a handler deals with errors; certain errors
-// (fatal, bug, unimpl) may cause immediate exit,
-// others log errors for later reporting.
+/// A handler deals with errors; certain errors
+/// (fatal, bug, unimpl) may cause immediate exit,
+/// others log errors for later reporting.
pub struct Handler {
err_count: Cell<uint>,
emit: RefCell<Box<Emitter + Send>>,
impl Handler {
pub fn fatal(&self, msg: &str) -> ! {
- self.emit.borrow_mut().emit(None, msg, Fatal);
+ self.emit.borrow_mut().emit(None, msg, None, Fatal);
fail!(FatalError);
}
pub fn err(&self, msg: &str) {
- self.emit.borrow_mut().emit(None, msg, Error);
+ self.emit.borrow_mut().emit(None, msg, None, Error);
self.bump_err_count();
}
pub fn bump_err_count(&self) {
self.fatal(s.as_slice());
}
pub fn warn(&self, msg: &str) {
- self.emit.borrow_mut().emit(None, msg, Warning);
+ self.emit.borrow_mut().emit(None, msg, None, Warning);
}
pub fn note(&self, msg: &str) {
- self.emit.borrow_mut().emit(None, msg, Note);
+ self.emit.borrow_mut().emit(None, msg, None, Note);
}
pub fn bug(&self, msg: &str) -> ! {
- self.emit.borrow_mut().emit(None, msg, Bug);
+ self.emit.borrow_mut().emit(None, msg, None, Bug);
fail!(ExplicitBug);
}
pub fn unimpl(&self, msg: &str) -> ! {
cmsp: Option<(&codemap::CodeMap, Span)>,
msg: &str,
lvl: Level) {
- self.emit.borrow_mut().emit(cmsp, msg, lvl);
+ self.emit.borrow_mut().emit(cmsp, msg, None, lvl);
+ }
+ pub fn emit_with_code(&self,
+ cmsp: Option<(&codemap::CodeMap, Span)>,
+ msg: &str,
+ code: &str,
+ lvl: Level) {
+ self.emit.borrow_mut().emit(cmsp, msg, Some(code), lvl);
}
pub fn custom_emit(&self, cm: &codemap::CodeMap,
sp: RenderSpan, msg: &str, lvl: Level) {
}
}
-pub fn default_handler(color_config: ColorConfig) -> Handler {
- mk_handler(box EmitterWriter::stderr(color_config))
+pub fn default_handler(color_config: ColorConfig,
+ registry: Option<diagnostics::registry::Registry>) -> Handler {
+ mk_handler(box EmitterWriter::stderr(color_config, registry))
}
pub fn mk_handler(e: Box<Emitter + Send>) -> Handler {
}
}
-fn print_diagnostic(dst: &mut EmitterWriter,
- topic: &str, lvl: Level, msg: &str) -> io::IoResult<()> {
+fn print_diagnostic(dst: &mut EmitterWriter, topic: &str, lvl: Level,
+ msg: &str, code: Option<&str>) -> io::IoResult<()> {
if !topic.is_empty() {
try!(write!(&mut dst.dst, "{} ", topic));
}
try!(print_maybe_styled(dst,
- format!("{}: ", lvl.to_str()).as_slice(),
+ format!("{}: ", lvl.to_string()).as_slice(),
term::attr::ForegroundColor(lvl.color())));
try!(print_maybe_styled(dst,
- format!("{}\n", msg).as_slice(),
+ format!("{}", msg).as_slice(),
term::attr::Bold));
+
+ match code {
+ Some(code) => {
+ let style = term::attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
+ try!(print_maybe_styled(dst, format!(" [{}]", code.clone()).as_slice(), style));
+ match dst.registry.as_ref().and_then(|registry| registry.find_description(code)) {
+ Some(_) => {
+ try!(write!(&mut dst.dst,
+ " (pass `--explain {}` to see a detailed explanation)",
+ code
+ ));
+ }
+ None => ()
+ }
+ }
+ None => ()
+ }
+ try!(dst.dst.write_char('\n'));
Ok(())
}
pub struct EmitterWriter {
dst: Destination,
+ registry: Option<diagnostics::registry::Registry>
}
enum Destination {
}
impl EmitterWriter {
- pub fn stderr(color_config: ColorConfig) -> EmitterWriter {
+ pub fn stderr(color_config: ColorConfig,
+ registry: Option<diagnostics::registry::Registry>) -> EmitterWriter {
let stderr = io::stderr();
let use_color = match color_config {
Some(t) => Terminal(t),
None => Raw(box stderr),
};
- EmitterWriter { dst: dst }
+ EmitterWriter { dst: dst, registry: registry }
} else {
- EmitterWriter { dst: Raw(box stderr) }
+ EmitterWriter { dst: Raw(box stderr), registry: registry }
}
}
- pub fn new(dst: Box<Writer + Send>) -> EmitterWriter {
- EmitterWriter { dst: Raw(dst) }
+ pub fn new(dst: Box<Writer + Send>,
+ registry: Option<diagnostics::registry::Registry>) -> EmitterWriter {
+ EmitterWriter { dst: Raw(dst), registry: registry }
}
}
impl Emitter for EmitterWriter {
fn emit(&mut self,
cmsp: Option<(&codemap::CodeMap, Span)>,
- msg: &str,
- lvl: Level) {
+ msg: &str, code: Option<&str>, lvl: Level) {
let error = match cmsp {
- Some((cm, sp)) => emit(self, cm, FullSpan(sp), msg, lvl, false),
- None => print_diagnostic(self, "", lvl, msg),
+ Some((cm, sp)) => emit(self, cm, FullSpan(sp), msg, code, lvl, false),
+ None => print_diagnostic(self, "", lvl, msg, code),
};
match error {
fn custom_emit(&mut self, cm: &codemap::CodeMap,
sp: RenderSpan, msg: &str, lvl: Level) {
- match emit(self, cm, sp, msg, lvl, true) {
+ match emit(self, cm, sp, msg, None, lvl, true) {
Ok(()) => {}
Err(e) => fail!("failed to print diagnostics: {}", e),
}
}
fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
- msg: &str, lvl: Level, custom: bool) -> io::IoResult<()> {
+ msg: &str, code: Option<&str>, lvl: Level, custom: bool) -> io::IoResult<()> {
let sp = rsp.span();
- let ss = cm.span_to_str(sp);
+ let ss = cm.span_to_string(sp);
let lines = cm.span_to_lines(sp);
if custom {
// we want to tell compiletest/runtest to look at the last line of the
// span (since `custom_highlight_lines` displays an arrow to the end of
// the span)
let span_end = Span { lo: sp.hi, hi: sp.hi, expn_info: sp.expn_info};
- let ses = cm.span_to_str(span_end);
- try!(print_diagnostic(dst, ses.as_slice(), lvl, msg));
+ let ses = cm.span_to_string(span_end);
+ try!(print_diagnostic(dst, ses.as_slice(), lvl, msg, code));
if rsp.is_full_span() {
try!(custom_highlight_lines(dst, cm, sp, lvl, lines));
}
} else {
- try!(print_diagnostic(dst, ss.as_slice(), lvl, msg));
+ try!(print_diagnostic(dst, ss.as_slice(), lvl, msg, code));
if rsp.is_full_span() {
try!(highlight_lines(dst, cm, sp, lvl, lines));
}
Ok(())
}
-// Here are the differences between this and the normal `highlight_lines`:
-// `custom_highlight_lines` will always put arrow on the last byte of the
-// span (instead of the first byte). Also, when the span is too long (more
-// than 6 lines), `custom_highlight_lines` will print the first line, then
-// dot dot dot, then last line, whereas `highlight_lines` prints the first
-// six lines.
+/// Here are the differences between this and the normal `highlight_lines`:
+/// `custom_highlight_lines` will always put arrow on the last byte of the
+/// span (instead of the first byte). Also, when the span is too long (more
+/// than 6 lines), `custom_highlight_lines` will print the first line, then
+/// dot dot dot, then last line, whereas `highlight_lines` prints the first
+/// six lines.
fn custom_highlight_lines(w: &mut EmitterWriter,
cm: &codemap::CodeMap,
sp: Span,
let ss = ei.callee
.span
.as_ref()
- .map_or("".to_string(), |span| cm.span_to_str(*span));
+ .map_or("".to_string(), |span| cm.span_to_string(*span));
let (pre, post) = match ei.callee.format {
codemap::MacroAttribute => ("#[", "]"),
codemap::MacroBang => ("", "!")
try!(print_diagnostic(w, ss.as_slice(), Note,
format!("in expansion of {}{}{}", pre,
ei.callee.name,
- post).as_slice()));
- let ss = cm.span_to_str(ei.call_site);
- try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site"));
+ post).as_slice(), None));
+ let ss = cm.span_to_string(ei.call_site);
+ try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site", None));
try!(print_macro_backtrace(w, cm, ei.call_site));
}
Ok(())
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![macro_escape]
+
+// NOTE: remove after next snapshot
+#[cfg(stage0)]
+#[macro_export]
+macro_rules! __register_diagnostic(
+ ($code:tt, $description:tt) => ();
+ ($code:tt) => ()
+)
+
+#[macro_export]
+macro_rules! register_diagnostic(
+ ($code:tt, $description:tt) => (__register_diagnostic!($code, $description));
+ ($code:tt) => (__register_diagnostic!($code))
+)
+
+// NOTE: remove after next snapshot
+#[cfg(stage0)]
+#[macro_export]
+macro_rules! __build_diagnostic_array(
+ ($name:ident) => {
+ pub static $name: [(&'static str, &'static str), ..0] = [];
+ }
+)
+
+// NOTE: remove after next snapshot
+#[cfg(stage0)]
+#[macro_export]
+macro_rules! __diagnostic_used(
+ ($code:ident) => {
+ ()
+ }
+)
+
+#[macro_export]
+macro_rules! span_err(
+ ($session:expr, $span:expr, $code:ident, $($arg:expr),*) => ({
+ __diagnostic_used!($code);
+ ($session).span_err_with_code($span, format!($($arg),*).as_slice(), stringify!($code))
+ })
+)
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::cell::RefCell;
+use std::collections::HashMap;
+use std::gc::Gc;
+use ast;
+use ast::{Ident, Name, TokenTree};
+use codemap::Span;
+use ext::base::{ExtCtxt, MacExpr, MacItem, MacResult};
+use ext::build::AstBuilder;
+use parse::token;
+
+local_data_key!(registered_diagnostics: RefCell<HashMap<Name, Option<Name>>>)
+local_data_key!(used_diagnostics: RefCell<HashMap<Name, Span>>)
+
+fn with_registered_diagnostics<T>(f: |&mut HashMap<Name, Option<Name>>| -> T) -> T {
+ match registered_diagnostics.get() {
+ Some(cell) => f(cell.borrow_mut().deref_mut()),
+ None => {
+ let mut map = HashMap::new();
+ let value = f(&mut map);
+ registered_diagnostics.replace(Some(RefCell::new(map)));
+ value
+ }
+ }
+}
+
+fn with_used_diagnostics<T>(f: |&mut HashMap<Name, Span>| -> T) -> T {
+ match used_diagnostics.get() {
+ Some(cell) => f(cell.borrow_mut().deref_mut()),
+ None => {
+ let mut map = HashMap::new();
+ let value = f(&mut map);
+ used_diagnostics.replace(Some(RefCell::new(map)));
+ value
+ }
+ }
+}
+
+pub fn expand_diagnostic_used(ecx: &mut ExtCtxt, span: Span,
+ token_tree: &[TokenTree]) -> Box<MacResult> {
+ let code = match token_tree {
+ [ast::TTTok(_, token::IDENT(code, _))] => code,
+ _ => unreachable!()
+ };
+ with_registered_diagnostics(|diagnostics| {
+ if !diagnostics.contains_key(&code.name) {
+ ecx.span_err(span, format!(
+ "unknown diagnostic code {}", token::get_ident(code).get()
+ ).as_slice());
+ }
+ ()
+ });
+ with_used_diagnostics(|diagnostics| {
+ match diagnostics.swap(code.name, span) {
+ Some(previous_span) => {
+ ecx.span_warn(span, format!(
+ "diagnostic code {} already used", token::get_ident(code).get()
+ ).as_slice());
+ ecx.span_note(previous_span, "previous invocation");
+ },
+ None => ()
+ }
+ ()
+ });
+ MacExpr::new(quote_expr!(ecx, ()))
+}
+
+pub fn expand_register_diagnostic(ecx: &mut ExtCtxt, span: Span,
+ token_tree: &[TokenTree]) -> Box<MacResult> {
+ let (code, description) = match token_tree {
+ [ast::TTTok(_, token::IDENT(ref code, _))] => {
+ (code, None)
+ },
+ [ast::TTTok(_, token::IDENT(ref code, _)),
+ ast::TTTok(_, token::COMMA),
+ ast::TTTok(_, token::LIT_STR_RAW(description, _))] => {
+ (code, Some(description))
+ }
+ _ => unreachable!()
+ };
+ with_registered_diagnostics(|diagnostics| {
+ if !diagnostics.insert(code.name, description) {
+ ecx.span_err(span, format!(
+ "diagnostic code {} already registered", token::get_ident(*code).get()
+ ).as_slice());
+ }
+ });
+ let sym = Ident::new(token::gensym((
+ "__register_diagnostic_".to_string() + token::get_ident(*code).get()
+ ).as_slice()));
+ MacItem::new(quote_item!(ecx, mod $sym {}).unwrap())
+}
+
+pub fn expand_build_diagnostic_array(ecx: &mut ExtCtxt, span: Span,
+ token_tree: &[TokenTree]) -> Box<MacResult> {
+ let name = match token_tree {
+ [ast::TTTok(_, token::IDENT(ref name, _))] => name,
+ _ => unreachable!()
+ };
+
+ let (count, expr) = with_used_diagnostics(|diagnostics_in_use| {
+ with_registered_diagnostics(|diagnostics| {
+ let descriptions: Vec<Gc<ast::Expr>> = diagnostics
+ .iter().filter_map(|(code, description)| {
+ if !diagnostics_in_use.contains_key(code) {
+ ecx.span_warn(span, format!(
+ "diagnostic code {} never used", token::get_name(*code).get()
+ ).as_slice());
+ }
+ description.map(|description| {
+ ecx.expr_tuple(span, vec![
+ ecx.expr_str(span, token::get_name(*code)),
+ ecx.expr_str(span, token::get_name(description))
+ ])
+ })
+ }).collect();
+ (descriptions.len(), ecx.expr_vec(span, descriptions))
+ })
+ });
+ MacItem::new(quote_item!(ecx,
+ pub static $name: [(&'static str, &'static str), ..$count] = $expr;
+ ).unwrap())
+}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::collections::HashMap;
+
+pub struct Registry {
+ descriptions: HashMap<&'static str, &'static str>
+}
+
+impl Registry {
+ pub fn new(descriptions: &[(&'static str, &'static str)]) -> Registry {
+ Registry { descriptions: descriptions.iter().map(|&tuple| tuple).collect() }
+ }
+
+ pub fn find_description(&self, code: &str) -> Option<&'static str> {
+ self.descriptions.find_equiv(&code).map(|desc| *desc)
+ }
+}
'statement: loop {
match state {
Asm => {
- let (s, style) = match expr_to_str(cx, p.parse_expr(),
+ let (s, style) = match expr_to_string(cx, p.parse_expr(),
"inline assembly must be a string literal.") {
Some((s, st)) => (s, st),
// let compilation continue
// Append an input operand, with the form of ("0", expr)
// that links to an output operand.
for &(i, out) in read_write_operands.iter() {
- inputs.push((token::intern_and_get_ident(i.to_str().as_slice()),
+ inputs.push((token::intern_and_get_ident(i.to_string().as_slice()),
out));
}
use parse::token;
use parse::token::{InternedString, intern, str_to_ident};
use util::small_vector::SmallVector;
+use ext::mtwt;
use std::collections::HashMap;
use std::gc::{Gc, GC};
pub span: Option<Span>
}
-pub trait MacroExpander {
+/// Represents a thing that maps token trees to Macro Results
+pub trait TTMacroExpander {
fn expand(&self,
ecx: &mut ExtCtxt,
span: Span,
fn(ecx: &mut ExtCtxt, span: codemap::Span, token_tree: &[ast::TokenTree])
-> Box<MacResult>;
-impl MacroExpander for BasicMacroExpander {
+impl TTMacroExpander for BasicMacroExpander {
fn expand(&self,
ecx: &mut ExtCtxt,
span: Span,
/// just into the compiler's internal macro table, for `make_def`).
pub trait MacResult {
/// Define a new macro.
+ // this should go away; the idea that a macro might expand into
+ // either a macro definition or an expression, depending on what
+ // the context wants, is kind of silly.
fn make_def(&self) -> Option<MacroDef> {
None
}
fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
None
}
+
+ /// Create zero or more methods.
+ fn make_methods(&self) -> Option<SmallVector<Gc<ast::Method>>> {
+ None
+ }
+
/// Create a pattern.
fn make_pat(&self) -> Option<Gc<ast::Pat>> {
None
span: sp,
}
}
+
}
impl MacResult for DummyResult {
Some(DummyResult::raw_pat(self.span))
}
fn make_items(&self) -> Option<SmallVector<Gc<ast::Item>>> {
+ // this code needs a comment... why not always just return the Some() ?
+ if self.expr_only {
+ None
+ } else {
+ Some(SmallVector::zero())
+ }
+ }
+ fn make_methods(&self) -> Option<SmallVector<Gc<ast::Method>>> {
if self.expr_only {
None
} else {
/// A normal, function-like syntax extension.
///
/// `bytes!` is a `NormalTT`.
- NormalTT(Box<MacroExpander + 'static>, Option<Span>),
+ NormalTT(Box<TTMacroExpander + 'static>, Option<Span>),
/// A function-like syntax extension that has an extra ident before
/// the block.
///
- /// `macro_rules!` is an `IdentTT`.
IdentTT(Box<IdentMacroExpander + 'static>, Option<Span>),
+
+ /// An ident macro that has two properties:
+ /// - it adds a macro definition to the environment, and
+ /// - the definition it adds doesn't introduce any new
+ /// identifiers.
+ ///
+ /// `macro_rules!` is a LetSyntaxTT
+ LetSyntaxTT(Box<IdentMacroExpander + 'static>, Option<Span>),
}
pub type NamedSyntaxExtension = (Name, SyntaxExtension);
pub struct BlockInfo {
- // should macros escape from this scope?
+ /// Should macros escape from this scope?
pub macros_escape: bool,
- // what are the pending renames?
- pub pending_renames: RenameList,
+ /// What are the pending renames?
+ pub pending_renames: mtwt::RenameList,
}
impl BlockInfo {
}
}
-// a list of ident->name renamings
-pub type RenameList = Vec<(ast::Ident, Name)>;
-
-// The base map of methods for expanding syntax extension
-// AST nodes into full ASTs
+/// The base map of methods for expanding syntax extension
+/// AST nodes into full ASTs
pub fn syntax_expander_table() -> SyntaxEnv {
// utility function to simplify creating NormalTT syntax extensions
fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
let mut syntax_expanders = SyntaxEnv::new();
syntax_expanders.insert(intern("macro_rules"),
- IdentTT(box BasicIdentMacroExpander {
+ LetSyntaxTT(box BasicIdentMacroExpander {
expander: ext::tt::macro_rules::add_new_extension,
span: None,
},
syntax_expanders
}
-// One of these is made during expansion and incrementally updated as we go;
-// when a macro expansion occurs, the resulting nodes have the backtrace()
-// -> expn_info of their expansion context stored into their span.
+/// One of these is made during expansion and incrementally updated as we go;
+/// when a macro expansion occurs, the resulting nodes have the backtrace()
+/// -> expn_info of their expansion context stored into their span.
pub struct ExtCtxt<'a> {
pub parse_sess: &'a parse::ParseSess,
pub cfg: ast::CrateConfig,
pub mod_path: Vec<ast::Ident> ,
pub trace_mac: bool,
+ pub exported_macros: Vec<codemap::Span>
}
impl<'a> ExtCtxt<'a> {
backtrace: None,
mod_path: Vec::new(),
ecfg: ecfg,
- trace_mac: false
+ trace_mac: false,
+ exported_macros: Vec::new(),
}
}
pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); }
pub fn mod_path(&self) -> Vec<ast::Ident> {
let mut v = Vec::new();
- v.push(token::str_to_ident(self.ecfg.crate_id.name.as_slice()));
+ v.push(token::str_to_ident(self.ecfg.crate_name.as_slice()));
v.extend(self.mod_path.iter().map(|a| *a));
return v;
}
pub fn ident_of(&self, st: &str) -> ast::Ident {
str_to_ident(st)
}
+ pub fn name_of(&self, st: &str) -> ast::Name {
+ token::intern(st)
+ }
+ pub fn push_exported_macro(&mut self, span: codemap::Span) {
+ self.exported_macros.push(span);
+ }
}
/// Extract a string literal from the macro expanded version of `expr`,
/// emitting `err_msg` if `expr` is not a string literal. This does not stop
/// compilation on error, merely emits a non-fatal error and returns None.
-pub fn expr_to_str(cx: &mut ExtCtxt, expr: Gc<ast::Expr>, err_msg: &str)
+pub fn expr_to_string(cx: &mut ExtCtxt, expr: Gc<ast::Expr>, err_msg: &str)
-> Option<(InternedString, ast::StrStyle)> {
// we want to be able to handle e.g. concat("foo", "bar")
let expr = cx.expand_expr(expr);
cx.span_err(sp, format!("{} takes 1 argument.", name).as_slice());
} else {
match tts[0] {
- ast::TTTok(_, token::LIT_STR(ident))
- | ast::TTTok(_, token::LIT_STR_RAW(ident, _)) => {
- return Some(token::get_ident(ident).get().to_string())
+ ast::TTTok(_, token::LIT_STR(ident)) => return Some(parse::str_lit(ident.as_str())),
+ ast::TTTok(_, token::LIT_STR_RAW(ident, _)) => {
+ return Some(parse::raw_str_lit(ident.as_str()))
}
_ => {
cx.span_err(sp,
Some(es)
}
-// in order to have some notion of scoping for macros,
-// we want to implement the notion of a transformation
-// environment.
+/// In order to have some notion of scoping for macros,
+/// we want to implement the notion of a transformation
+/// environment.
-// This environment maps Names to SyntaxExtensions.
+/// This environment maps Names to SyntaxExtensions.
//impl question: how to implement it? Initially, the
// env will contain only macros, so it might be painful
map: HashMap<Name, SyntaxExtension>,
}
-// Only generic to make it easy to test
pub struct SyntaxEnv {
chain: Vec<MapChainFrame> ,
}
fn typaram(&self,
span: Span,
id: ast::Ident,
- sized: ast::Sized,
bounds: OwnedSlice<ast::TyParamBound>,
+ unbound: Option<ast::TyParamBound>,
default: Option<P<ast::Ty>>) -> ast::TyParam;
fn trait_ref(&self, path: ast::Path) -> ast::TraitRef;
fn expr_some(&self, sp: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr>;
fn expr_none(&self, sp: Span) -> Gc<ast::Expr>;
+ fn expr_tuple(&self, sp: Span, exprs: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr>;
+
fn expr_fail(&self, span: Span, msg: InternedString) -> Gc<ast::Expr>;
fn expr_unreachable(&self, span: Span) -> Gc<ast::Expr>;
fn typaram(&self,
span: Span,
id: ast::Ident,
- sized: ast::Sized,
bounds: OwnedSlice<ast::TyParamBound>,
+ unbound: Option<ast::TyParamBound>,
default: Option<P<ast::Ty>>) -> ast::TyParam {
ast::TyParam {
ident: id,
id: ast::DUMMY_NODE_ID,
- sized: sized,
bounds: bounds,
+ unbound: unbound,
default: default,
span: span
}
fn strip_bounds(&self, generics: &Generics) -> Generics {
let new_params = generics.ty_params.map(|ty_param| {
- ast::TyParam { bounds: OwnedSlice::empty(), ..*ty_param }
+ ast::TyParam { bounds: OwnedSlice::empty(), unbound: None, ..*ty_param }
});
Generics {
ty_params: new_params,
self.expr_path(none)
}
+ fn expr_tuple(&self, sp: Span, exprs: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr> {
+ self.expr(sp, ast::ExprTup(exprs))
+ }
+
fn expr_fail(&self, span: Span, msg: InternedString) -> Gc<ast::Expr> {
let loc = self.codemap().lookup_char_pos(span.lo);
self.expr_call_global(
args: Vec::new(),
ret_ty: Self,
attributes: attrs,
- const_nonmatching: false,
combine_substructure: combine_substructure(|c, s, sub| {
cs_clone("Clone", c, s, sub)
}),
ctor_ident = variant.node.name;
all_fields = af;
},
- EnumNonMatching(..) => {
+ EnumNonMatchingCollapsed (..) => {
cx.span_bug(trait_span,
format!("non-matching enum variants in \
`deriving({})`",
args: vec!(borrowed_self()),
ret_ty: Literal(Path::new(vec!("bool"))),
attributes: attrs,
- const_nonmatching: true,
combine_substructure: combine_substructure(|a, b, c| {
$f(a, b, c)
})
args: vec!(borrowed_self()),
ret_ty: Literal(Path::new(vec!("bool"))),
attributes: attrs,
- const_nonmatching: false,
combine_substructure: combine_substructure(|cx, span, substr| {
cs_op($op, $equal, cx, span, substr)
})
args: vec![borrowed_self()],
ret_ty: ret_ty,
attributes: attrs,
- const_nonmatching: false,
combine_substructure: combine_substructure(|cx, span, substr| {
cs_partial_cmp(cx, span, substr)
})
trait_def.expand(cx, mitem, item, push)
}
-pub fn some_ordering_const(cx: &mut ExtCtxt, span: Span, cnst: Ordering) -> Gc<ast::Expr> {
- let cnst = match cnst {
- Less => "Less",
- Equal => "Equal",
- Greater => "Greater"
+pub enum OrderingOp {
+ PartialCmpOp, LtOp, LeOp, GtOp, GeOp,
+}
+
+pub fn some_ordering_collapsed(cx: &mut ExtCtxt,
+ span: Span,
+ op: OrderingOp,
+ self_arg_tags: &[ast::Ident]) -> Gc<ast::Expr> {
+ let lft = cx.expr_ident(span, self_arg_tags[0]);
+ let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
+ let op_str = match op {
+ PartialCmpOp => "partial_cmp",
+ LtOp => "lt", LeOp => "le",
+ GtOp => "gt", GeOp => "ge",
};
- let ordering = cx.path_global(span,
- vec!(cx.ident_of("std"),
- cx.ident_of("cmp"),
- cx.ident_of(cnst)));
- let ordering = cx.expr_path(ordering);
- cx.expr_some(span, ordering)
+ cx.expr_method_call(span, lft, cx.ident_of(op_str), vec![rgt])
}
pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> Gc<Expr> {
let test_id = cx.ident_of("__test");
- let equals_expr = some_ordering_const(cx, span, Equal);
+ let ordering = cx.path_global(span,
+ vec!(cx.ident_of("std"),
+ cx.ident_of("cmp"),
+ cx.ident_of("Equal")));
+ let ordering = cx.expr_path(ordering);
+ let equals_expr = cx.expr_some(span, ordering);
/*
Builds:
cx.expr_block(cx.block(span, vec!(assign), Some(if_)))
},
equals_expr.clone(),
- |cx, span, list, _| {
- match list {
- // an earlier nonmatching variant is Less than a
- // later one.
- [(self_var, _, _), (other_var, _, _)] =>
- some_ordering_const(cx, span, self_var.cmp(&other_var)),
- _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`")
+ |cx, span, (self_args, tag_tuple), _non_self_args| {
+ if self_args.len() != 2 {
+ cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`")
+ } else {
+ some_ordering_collapsed(cx, span, PartialCmpOp, tag_tuple)
}
},
cx, span, substr)
cx.expr_binary(span, ast::BiOr, cmp, and)
},
cx.expr_bool(span, equal),
- |cx, span, args, _| {
- // nonmatching enums, order by the order the variants are
- // written
- match args {
- [(self_var, _, _),
- (other_var, _, _)] =>
- cx.expr_bool(span,
- if less {
- self_var < other_var
- } else {
- self_var > other_var
- }),
- _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`")
+ |cx, span, (self_args, tag_tuple), _non_self_args| {
+ if self_args.len() != 2 {
+ cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`")
+ } else {
+ let op = match (less, equal) {
+ (true, true) => LeOp, (true, false) => LtOp,
+ (false, true) => GeOp, (false, false) => GtOp,
+ };
+ some_ordering_collapsed(cx, span, op, tag_tuple)
}
},
cx, span, substr)
args: vec!(),
ret_ty: nil_ty(),
attributes: attrs,
- const_nonmatching: true,
combine_substructure: combine_substructure(|a, b, c| {
cs_total_eq_assert(a, b, c)
})
use ext::deriving::generic::ty::*;
use parse::token::InternedString;
-use std::cmp::{Ordering, Equal, Less, Greater};
use std::gc::Gc;
pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
args: vec!(borrowed_self()),
ret_ty: Literal(Path::new(vec!("std", "cmp", "Ordering"))),
attributes: attrs,
- const_nonmatching: false,
combine_substructure: combine_substructure(|a, b, c| {
cs_cmp(a, b, c)
}),
}
-pub fn ordering_const(cx: &mut ExtCtxt, span: Span, cnst: Ordering) -> ast::Path {
- let cnst = match cnst {
- Less => "Less",
- Equal => "Equal",
- Greater => "Greater"
- };
- cx.path_global(span,
- vec!(cx.ident_of("std"),
- cx.ident_of("cmp"),
- cx.ident_of(cnst)))
+pub fn ordering_collapsed(cx: &mut ExtCtxt,
+ span: Span,
+ self_arg_tags: &[ast::Ident]) -> Gc<ast::Expr> {
+ let lft = cx.expr_ident(span, self_arg_tags[0]);
+ let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
+ cx.expr_method_call(span, lft, cx.ident_of("cmp"), vec![rgt])
}
pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> Gc<Expr> {
let test_id = cx.ident_of("__test");
- let equals_path = ordering_const(cx, span, Equal);
+ let equals_path = cx.path_global(span,
+ vec!(cx.ident_of("std"),
+ cx.ident_of("cmp"),
+ cx.ident_of("Equal")));
/*
Builds:
cx.expr_block(cx.block(span, vec!(assign), Some(if_)))
},
cx.expr_path(equals_path.clone()),
- |cx, span, list, _| {
- match list {
- // an earlier nonmatching variant is Less than a
- // later one.
- [(self_var, _, _),
- (other_var, _, _)] => {
- let order = ordering_const(cx, span, self_var.cmp(&other_var));
- cx.expr_path(order)
- }
- _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`")
+ |cx, span, (self_args, tag_tuple), _non_self_args| {
+ if self_args.len() != 2 {
+ cx.span_bug(span, "not exactly 2 arguments in `deriving(TotalOrd)`")
+ } else {
+ ordering_collapsed(cx, span, tag_tuple)
}
},
cx, span, substr)
encodable.rs for more.
*/
-use ast;
use ast::{MetaItem, Item, Expr, MutMutable, Ident};
use codemap::Span;
use ext::base::ExtCtxt;
additional_bounds: Vec::new(),
generics: LifetimeBounds {
lifetimes: Vec::new(),
- bounds: vec!(("__D", ast::StaticSize, vec!(Path::new_(
+ bounds: vec!(("__D", None, vec!(Path::new_(
vec!("serialize", "Decoder"), None,
vec!(box Literal(Path::new_local("__E"))), true))),
- ("__E", ast::StaticSize, vec!()))
+ ("__E", None, vec!()))
},
methods: vec!(
MethodDef {
vec!(box Self,
box Literal(Path::new_local("__E"))), true)),
attributes: Vec::new(),
- const_nonmatching: true,
combine_substructure: combine_substructure(|a, b, c| {
decodable_substructure(a, b, c)
}),
args: Vec::new(),
ret_ty: Self,
attributes: attrs,
- const_nonmatching: false,
combine_substructure: combine_substructure(|a, b, c| {
default_substructure(a, b, c)
})
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-/*!
+//! The compiler code necessary to implement the `#[deriving(Encodable)]`
+//! (and `Decodable`, in decodable.rs) extension. The idea here is that
+//! type-defining items may be tagged with `#[deriving(Encodable, Decodable)]`.
+//!
+//! For example, a type like:
+//!
+//! ```ignore
+//! #[deriving(Encodable, Decodable)]
+//! struct Node { id: uint }
+//! ```
+//!
+//! would generate two implementations like:
+//!
+//! ```ignore
+//! impl<S:serialize::Encoder> Encodable<S> for Node {
+//! fn encode(&self, s: &S) {
+//! s.emit_struct("Node", 1, || {
+//! s.emit_field("id", 0, || s.emit_uint(self.id))
+//! })
+//! }
+//! }
+//!
+//! impl<D:Decoder> Decodable for node_id {
+//! fn decode(d: &D) -> Node {
+//! d.read_struct("Node", 1, || {
+//! Node {
+//! id: d.read_field("x".to_string(), 0, || decode(d))
+//! }
+//! })
+//! }
+//! }
+//! ```
+//!
+//! Other interesting scenarios are whe the item has type parameters or
+//! references other non-built-in types. A type definition like:
+//!
+//! ```ignore
+//! #[deriving(Encodable, Decodable)]
+//! struct spanned<T> { node: T, span: Span }
+//! ```
+//!
+//! would yield functions like:
+//!
+//! ```ignore
+//! impl<
+//! S: Encoder,
+//! T: Encodable<S>
+//! > spanned<T>: Encodable<S> {
+//! fn encode<S:Encoder>(s: &S) {
+//! s.emit_rec(|| {
+//! s.emit_field("node", 0, || self.node.encode(s));
+//! s.emit_field("span", 1, || self.span.encode(s));
+//! })
+//! }
+//! }
+//!
+//! impl<
+//! D: Decoder,
+//! T: Decodable<D>
+//! > spanned<T>: Decodable<D> {
+//! fn decode(d: &D) -> spanned<T> {
+//! d.read_rec(|| {
+//! {
+//! node: d.read_field("node".to_string(), 0, || decode(d)),
+//! span: d.read_field("span".to_string(), 1, || decode(d)),
+//! }
+//! })
+//! }
+//! }
+//! ```
-The compiler code necessary to implement the `#[deriving(Encodable)]`
-(and `Decodable`, in decodable.rs) extension. The idea here is that
-type-defining items may be tagged with `#[deriving(Encodable, Decodable)]`.
-
-For example, a type like:
-
-```ignore
-#[deriving(Encodable, Decodable)]
-struct Node { id: uint }
-```
-
-would generate two implementations like:
-
-```ignore
-impl<S:serialize::Encoder> Encodable<S> for Node {
- fn encode(&self, s: &S) {
- s.emit_struct("Node", 1, || {
- s.emit_field("id", 0, || s.emit_uint(self.id))
- })
- }
-}
-
-impl<D:Decoder> Decodable for node_id {
- fn decode(d: &D) -> Node {
- d.read_struct("Node", 1, || {
- Node {
- id: d.read_field("x".to_string(), 0, || decode(d))
- }
- })
- }
-}
-```
-
-Other interesting scenarios are whe the item has type parameters or
-references other non-built-in types. A type definition like:
-
-```ignore
-#[deriving(Encodable, Decodable)]
-struct spanned<T> { node: T, span: Span }
-```
-
-would yield functions like:
-
-```ignore
- impl<
- S: Encoder,
- T: Encodable<S>
- > spanned<T>: Encodable<S> {
- fn encode<S:Encoder>(s: &S) {
- s.emit_rec(|| {
- s.emit_field("node", 0, || self.node.encode(s));
- s.emit_field("span", 1, || self.span.encode(s));
- })
- }
- }
-
- impl<
- D: Decoder,
- T: Decodable<D>
- > spanned<T>: Decodable<D> {
- fn decode(d: &D) -> spanned<T> {
- d.read_rec(|| {
- {
- node: d.read_field("node".to_string(), 0, || decode(d)),
- span: d.read_field("span".to_string(), 1, || decode(d)),
- }
- })
- }
- }
-```
-*/
-
-use ast;
use ast::{MetaItem, Item, Expr, ExprRet, MutMutable, LitNil};
use codemap::Span;
use ext::base::ExtCtxt;
additional_bounds: Vec::new(),
generics: LifetimeBounds {
lifetimes: Vec::new(),
- bounds: vec!(("__S", ast::StaticSize, vec!(Path::new_(
+ bounds: vec!(("__S", None, vec!(Path::new_(
vec!("serialize", "Encoder"), None,
vec!(box Literal(Path::new_local("__E"))), true))),
- ("__E", ast::StaticSize, vec!()))
+ ("__E", None, vec!()))
},
methods: vec!(
MethodDef {
box Literal(Path::new_local("__E"))),
true)),
attributes: Vec::new(),
- const_nonmatching: true,
combine_substructure: combine_substructure(|a, b, c| {
encodable_substructure(a, b, c)
}),
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-/*!
-
-Some code that abstracts away much of the boilerplate of writing
-`deriving` instances for traits. Among other things it manages getting
-access to the fields of the 4 different sorts of structs and enum
-variants, as well as creating the method and impl ast instances.
-
-Supported features (fairly exhaustive):
-
-- Methods taking any number of parameters of any type, and returning
- any type, other than vectors, bottom and closures.
-- Generating `impl`s for types with type parameters and lifetimes
- (e.g. `Option<T>`), the parameters are automatically given the
- current trait as a bound. (This includes separate type parameters
- and lifetimes for methods.)
-- Additional bounds on the type parameters, e.g. the `Ord` instance
- requires an explicit `PartialEq` bound at the
- moment. (`TraitDef.additional_bounds`)
-
-Unsupported: FIXME #6257: calling methods on reference fields,
-e.g. deriving Eq/Ord/Clone don't work on `struct A(&int)`,
-because of how the auto-dereferencing happens.
-
-The most important thing for implementers is the `Substructure` and
-`SubstructureFields` objects. The latter groups 5 possibilities of the
-arguments:
-
-- `Struct`, when `Self` is a struct (including tuple structs, e.g
- `struct T(int, char)`).
-- `EnumMatching`, when `Self` is an enum and all the arguments are the
- same variant of the enum (e.g. `Some(1)`, `Some(3)` and `Some(4)`)
-- `EnumNonMatching` when `Self` is an enum and the arguments are not
- the same variant (e.g. `None`, `Some(1)` and `None`). If
- `const_nonmatching` is true, this will contain an empty list.
-- `StaticEnum` and `StaticStruct` for static methods, where the type
- being derived upon is either an enum or struct respectively. (Any
- argument with type Self is just grouped among the non-self
- arguments.)
-
-In the first two cases, the values from the corresponding fields in
-all the arguments are grouped together. In the `EnumNonMatching` case
-this isn't possible (different variants have different fields), so the
-fields are grouped by which argument they come from. There are no
-fields with values in the static cases, so these are treated entirely
-differently.
-
-The non-static cases have `Option<ident>` in several places associated
-with field `expr`s. This represents the name of the field it is
-associated with. It is only not `None` when the associated field has
-an identifier in the source code. For example, the `x`s in the
-following snippet
-
-```rust
-struct A { x : int }
-
-struct B(int);
-
-enum C {
- C0(int),
- C1 { x: int }
-}
-```
-
-The `int`s in `B` and `C0` don't have an identifier, so the
-`Option<ident>`s would be `None` for them.
-
-In the static cases, the structure is summarised, either into the just
-spans of the fields or a list of spans and the field idents (for tuple
-structs and record structs, respectively), or a list of these, for
-enums (one for each variant). For empty struct and empty enum
-variants, it is represented as a count of 0.
-
-# Examples
-
-The following simplified `PartialEq` is used for in-code examples:
-
-```rust
-trait PartialEq {
- fn eq(&self, other: &Self);
-}
-impl PartialEq for int {
- fn eq(&self, other: &int) -> bool {
- *self == *other
- }
-}
-```
-
-Some examples of the values of `SubstructureFields` follow, using the
-above `PartialEq`, `A`, `B` and `C`.
-
-## Structs
-
-When generating the `expr` for the `A` impl, the `SubstructureFields` is
-
-~~~text
-Struct(~[FieldInfo {
- span: <span of x>
- name: Some(<ident of x>),
- self_: <expr for &self.x>,
- other: ~[<expr for &other.x]
- }])
-~~~
-
-For the `B` impl, called with `B(a)` and `B(b)`,
-
-~~~text
-Struct(~[FieldInfo {
- span: <span of `int`>,
- name: None,
- <expr for &a>
- ~[<expr for &b>]
- }])
-~~~
-
-## Enums
-
-When generating the `expr` for a call with `self == C0(a)` and `other
-== C0(b)`, the SubstructureFields is
-
-~~~text
-EnumMatching(0, <ast::Variant for C0>,
- ~[FieldInfo {
- span: <span of int>
- name: None,
- self_: <expr for &a>,
- other: ~[<expr for &b>]
- }])
-~~~
-
-For `C1 {x}` and `C1 {x}`,
-
-~~~text
-EnumMatching(1, <ast::Variant for C1>,
- ~[FieldInfo {
- span: <span of x>
- name: Some(<ident of x>),
- self_: <expr for &self.x>,
- other: ~[<expr for &other.x>]
- }])
-~~~
-
-For `C0(a)` and `C1 {x}` ,
-
-~~~text
-EnumNonMatching(~[(0, <ast::Variant for B0>,
- ~[(<span of int>, None, <expr for &a>)]),
- (1, <ast::Variant for B1>,
- ~[(<span of x>, Some(<ident of x>),
- <expr for &other.x>)])])
-~~~
-
-(and vice versa, but with the order of the outermost list flipped.)
-
-## Static
-
-A static method on the above would result in,
-
-~~~text
-StaticStruct(<ast::StructDef of A>, Named(~[(<ident of x>, <span of x>)]))
-
-StaticStruct(<ast::StructDef of B>, Unnamed(~[<span of x>]))
-
-StaticEnum(<ast::EnumDef of C>, ~[(<ident of C0>, <span of C0>, Unnamed(~[<span of int>])),
- (<ident of C1>, <span of C1>,
- Named(~[(<ident of x>, <span of x>)]))])
-~~~
-
-*/
+//! Some code that abstracts away much of the boilerplate of writing
+//! `deriving` instances for traits. Among other things it manages getting
+//! access to the fields of the 4 different sorts of structs and enum
+//! variants, as well as creating the method and impl ast instances.
+//!
+//! Supported features (fairly exhaustive):
+//!
+//! - Methods taking any number of parameters of any type, and returning
+//! any type, other than vectors, bottom and closures.
+//! - Generating `impl`s for types with type parameters and lifetimes
+//! (e.g. `Option<T>`), the parameters are automatically given the
+//! current trait as a bound. (This includes separate type parameters
+//! and lifetimes for methods.)
+//! - Additional bounds on the type parameters, e.g. the `Ord` instance
+//! requires an explicit `PartialEq` bound at the
+//! moment. (`TraitDef.additional_bounds`)
+//!
+//! Unsupported: FIXME #6257: calling methods on reference fields,
+//! e.g. deriving Eq/Ord/Clone don't work on `struct A(&int)`,
+//! because of how the auto-dereferencing happens.
+//!
+//! The most important thing for implementers is the `Substructure` and
+//! `SubstructureFields` objects. The latter groups 5 possibilities of the
+//! arguments:
+//!
+//! - `Struct`, when `Self` is a struct (including tuple structs, e.g
+//! `struct T(int, char)`).
+//! - `EnumMatching`, when `Self` is an enum and all the arguments are the
+//! same variant of the enum (e.g. `Some(1)`, `Some(3)` and `Some(4)`)
+//! - `EnumNonMatchingCollapsed` when `Self` is an enum and the arguments
+//! are not the same variant (e.g. `None`, `Some(1)` and `None`).
+//! - `StaticEnum` and `StaticStruct` for static methods, where the type
+//! being derived upon is either an enum or struct respectively. (Any
+//! argument with type Self is just grouped among the non-self
+//! arguments.)
+//!
+//! In the first two cases, the values from the corresponding fields in
+//! all the arguments are grouped together. For `EnumNonMatchingCollapsed`
+//! this isn't possible (different variants have different fields), so the
+//! fields are inaccessible. (Previous versions of the deriving infrastructure
+//! had a way to expand into code that could access them, at the cost of
+//! generating exponential amounts of code; see issue #15375). There are no
+//! fields with values in the static cases, so these are treated entirely
+//! differently.
+//!
+//! The non-static cases have `Option<ident>` in several places associated
+//! with field `expr`s. This represents the name of the field it is
+//! associated with. It is only not `None` when the associated field has
+//! an identifier in the source code. For example, the `x`s in the
+//! following snippet
+//!
+//! ```rust
+//! struct A { x : int }
+//!
+//! struct B(int);
+//!
+//! enum C {
+//! C0(int),
+//! C1 { x: int }
+//! }
+//! ```
+//!
+//! The `int`s in `B` and `C0` don't have an identifier, so the
+//! `Option<ident>`s would be `None` for them.
+//!
+//! In the static cases, the structure is summarised, either into the just
+//! spans of the fields or a list of spans and the field idents (for tuple
+//! structs and record structs, respectively), or a list of these, for
+//! enums (one for each variant). For empty struct and empty enum
+//! variants, it is represented as a count of 0.
+//!
+//! # Examples
+//!
+//! The following simplified `PartialEq` is used for in-code examples:
+//!
+//! ```rust
+//! trait PartialEq {
+//! fn eq(&self, other: &Self);
+//! }
+//! impl PartialEq for int {
+//! fn eq(&self, other: &int) -> bool {
+//! *self == *other
+//! }
+//! }
+//! ```
+//!
+//! Some examples of the values of `SubstructureFields` follow, using the
+//! above `PartialEq`, `A`, `B` and `C`.
+//!
+//! ## Structs
+//!
+//! When generating the `expr` for the `A` impl, the `SubstructureFields` is
+//!
+//! ~~~text
+//! Struct(~[FieldInfo {
+//! span: <span of x>
+//! name: Some(<ident of x>),
+//! self_: <expr for &self.x>,
+//! other: ~[<expr for &other.x]
+//! }])
+//! ~~~
+//!
+//! For the `B` impl, called with `B(a)` and `B(b)`,
+//!
+//! ~~~text
+//! Struct(~[FieldInfo {
+//! span: <span of `int`>,
+//! name: None,
+//! <expr for &a>
+//! ~[<expr for &b>]
+//! }])
+//! ~~~
+//!
+//! ## Enums
+//!
+//! When generating the `expr` for a call with `self == C0(a)` and `other
+//! == C0(b)`, the SubstructureFields is
+//!
+//! ~~~text
+//! EnumMatching(0, <ast::Variant for C0>,
+//! ~[FieldInfo {
+//! span: <span of int>
+//! name: None,
+//! self_: <expr for &a>,
+//! other: ~[<expr for &b>]
+//! }])
+//! ~~~
+//!
+//! For `C1 {x}` and `C1 {x}`,
+//!
+//! ~~~text
+//! EnumMatching(1, <ast::Variant for C1>,
+//! ~[FieldInfo {
+//! span: <span of x>
+//! name: Some(<ident of x>),
+//! self_: <expr for &self.x>,
+//! other: ~[<expr for &other.x>]
+//! }])
+//! ~~~
+//!
+//! For `C0(a)` and `C1 {x}` ,
+//!
+//! ~~~text
+//! EnumNonMatchingCollapsed(
+//! ~[<ident of self>, <ident of __arg_1>],
+//! &[<ast::Variant for C0>, <ast::Variant for C1>],
+//! &[<ident for self index value>, <ident of __arg_1 index value>])
+//! ~~~
+//!
+//! It is the same for when the arguments are flipped to `C1 {x}` and
+//! `C0(a)`; the only difference is what the values of the identifiers
+//! <ident for self index value> and <ident of __arg_1 index value> will
+//! be in the generated code.
+//!
+//! `EnumNonMatchingCollapsed` deliberately provides far less information
+//! than is generally available for a given pair of variants; see #15375
+//! for discussion.
+//!
+//! ## Static
+//!
+//! A static method on the above would result in,
+//!
+//! ~~~text
+//! StaticStruct(<ast::StructDef of A>, Named(~[(<ident of x>, <span of x>)]))
+//!
+//! StaticStruct(<ast::StructDef of B>, Unnamed(~[<span of x>]))
+//!
+//! StaticEnum(<ast::EnumDef of C>, ~[(<ident of C0>, <span of C0>, Unnamed(~[<span of int>])),
+//! (<ident of C1>, <span of C1>,
+//! Named(~[(<ident of x>, <span of x>)]))])
+//! ~~~
use std::cell::RefCell;
use std::gc::{Gc, GC};
use codemap::Span;
use owned_slice::OwnedSlice;
use parse::token::InternedString;
+use parse::token::special_idents;
use self::ty::*;
pub attributes: Vec<ast::Attribute>,
- /// if the value of the nonmatching enums is independent of the
- /// actual enum variants, i.e. can use _ => .. match.
- pub const_nonmatching: bool,
-
pub combine_substructure: RefCell<CombineSubstructureFunc<'a>>,
}
EnumMatching(uint, &'a ast::Variant, Vec<FieldInfo>),
/**
- non-matching variants of the enum, [(variant index, ast::Variant,
- [field span, field ident, fields])] \(i.e. all fields for self are in the
- first tuple, for other1 are in the second tuple, etc.)
+ non-matching variants of the enum, but with all state hidden from
+ the consequent code. The first component holds Idents for all of
+ the Self arguments; the second component is a slice of all of the
+ variants for the enum itself, and the third component is a list of
+ Idents bound to the variant index values for each of the actual
+ input Self arguments.
*/
- EnumNonMatching(&'a [(uint, P<ast::Variant>,
- Vec<(Span, Option<Ident>, Gc<Expr>)>)]),
+ EnumNonMatchingCollapsed(Vec<Ident>, &'a [Gc<ast::Variant>], &'a [Ident]),
/// A static method where Self is a struct.
StaticStruct(&'a ast::StructDef, StaticFields),
|&mut ExtCtxt, Span, &Substructure|: 'a -> Gc<Expr>;
/**
-Deal with non-matching enum variants, the arguments are a list
-representing each variant: (variant index, ast::Variant instance,
-[variant fields]), and a list of the nonself args of the type
+Deal with non-matching enum variants. The tuple is a list of
+identifiers (one for each Self argument, which could be any of the
+variants since they have been collapsed together) and the identifiers
+holding the variant index value for each of the Self arguments. The
+last argument is all the non-Self args of the method being derived.
*/
-pub type EnumNonMatchFunc<'a> =
+pub type EnumNonMatchCollapsedFunc<'a> =
|&mut ExtCtxt,
Span,
- &[(uint, P<ast::Variant>, Vec<(Span, Option<Ident>, Gc<Expr>)>)],
+ (&[Ident], &[Ident]),
&[Gc<Expr>]|: 'a
-> Gc<Expr>;
cx.typaram(self.span,
ty_param.ident,
- ty_param.sized,
OwnedSlice::from_vec(bounds),
+ ty_param.unbound.clone(),
None)
}));
let trait_generics = Generics {
}
}
+fn variant_to_pat(cx: &mut ExtCtxt, sp: Span, variant: &ast::Variant)
+ -> Gc<ast::Pat> {
+ let ident = cx.path_ident(sp, variant.node.name);
+ cx.pat(sp, match variant.node.kind {
+ ast::TupleVariantKind(..) => ast::PatEnum(ident, None),
+ ast::StructVariantKind(..) => ast::PatStruct(ident, Vec::new(), true),
+ })
+}
+
impl<'a> MethodDef<'a> {
fn call_substructure_method(&self,
cx: &mut ExtCtxt,
let self_arg = match explicit_self.node {
ast::SelfStatic => None,
- _ => Some(ast::Arg::new_self(trait_.span, ast::MutImmutable))
+ // creating fresh self id
+ _ => Some(ast::Arg::new_self(trait_.span, ast::MutImmutable, special_idents::self_))
};
let args = {
let args = arg_types.move_iter().map(|(name, ty)| {
// Create the method.
box(GC) ast::Method {
- ident: method_ident,
attrs: self.attributes.clone(),
- generics: fn_generics,
- explicit_self: explicit_self,
- fn_style: ast::NormalFn,
- decl: fn_decl,
- body: body_block,
id: ast::DUMMY_NODE_ID,
span: trait_.span,
- vis: ast::Inherited,
+ node: ast::MethDecl(method_ident,
+ fn_generics,
+ explicit_self,
+ ast::NormalFn,
+ fn_decl,
+ body_block,
+ ast::Inherited)
}
}
~~~
#[deriving(PartialEq)]
enum A {
- A1
+ A1,
A2(int)
}
- // is equivalent to (with const_nonmatching == false)
+ // is equivalent to
impl PartialEq for A {
- fn eq(&self, __arg_1: &A) {
- match *self {
- A1 => match *__arg_1 {
- A1 => true
- A2(ref __arg_1_1) => false
- },
- A2(self_1) => match *__arg_1 {
- A1 => false,
- A2(ref __arg_1_1) => self_1.eq(__arg_1_1)
+ fn eq(&self, __arg_1: &A) -> ::bool {
+ match (&*self, &*__arg_1) {
+ (&A1, &A1) => true,
+ (&A2(ref __self_0),
+ &A2(ref __arg_1_0)) => (*__self_0).eq(&(*__arg_1_0)),
+ _ => {
+ let __self_vi = match *self { A1(..) => 0u, A2(..) => 1u };
+ let __arg_1_vi = match *__arg_1 { A1(..) => 0u, A2(..) => 1u };
+ false
}
}
}
}
~~~
+
+ (Of course `__self_vi` and `__arg_1_vi` are unused for
+ `PartialEq`, and those subcomputations will hopefully be removed
+ as their results are unused. The point of `__self_vi` and
+ `__arg_1_vi` is for `PartialOrd`; see #15503.)
*/
fn expand_enum_method_body(&self,
cx: &mut ExtCtxt,
self_args: &[Gc<Expr>],
nonself_args: &[Gc<Expr>])
-> Gc<Expr> {
- let mut matches = Vec::new();
- self.build_enum_match(cx, trait_, enum_def, type_ident,
- self_args, nonself_args,
- None, &mut matches, 0)
+ self.build_enum_match_tuple(
+ cx, trait_, enum_def, type_ident, self_args, nonself_args)
}
/**
- Creates the nested matches for an enum definition recursively, i.e.
-
- ~~~text
- match self {
- Variant1 => match other { Variant1 => matching, Variant2 => nonmatching, ... },
- Variant2 => match other { Variant1 => nonmatching, Variant2 => matching, ... },
- ...
+ Creates a match for a tuple of all `self_args`, where either all
+ variants match, or it falls into a catch-all for when one variant
+ does not match.
+
+ There are N + 1 cases because is a case for each of the N
+ variants where all of the variants match, and one catch-all for
+ when one does not match.
+
+ The catch-all handler is provided access the variant index values
+ for each of the self-args, carried in precomputed variables. (Nota
+ bene: the variant index values are not necessarily the
+ discriminant values. See issue #15523.)
+
+ ~~~text
+ match (this, that, ...) {
+ (Variant1, Variant1, Variant1) => ... // delegate Matching on Variant1
+ (Variant2, Variant2, Variant2) => ... // delegate Matching on Variant2
+ ...
+ _ => {
+ let __this_vi = match this { Variant1 => 0u, Variant2 => 1u, ... };
+ let __that_vi = match that { Variant1 => 0u, Variant2 => 1u, ... };
+ ... // catch-all remainder can inspect above variant index values.
+ }
}
- ~~~
-
- It acts in the most naive way, so every branch (and subbranch,
- subsubbranch, etc) exists, not just the ones where all the variants in
- the tree are the same. Hopefully the optimisers get rid of any
- repetition, otherwise derived methods with many Self arguments will be
- exponentially large.
-
- `matching` is Some(n) if all branches in the tree above the
- current position are variant `n`, `None` otherwise (including on
- the first call).
+ ~~~
*/
- fn build_enum_match(&self,
- cx: &mut ExtCtxt,
- trait_: &TraitDef,
- enum_def: &EnumDef,
- type_ident: Ident,
- self_args: &[Gc<Expr>],
- nonself_args: &[Gc<Expr>],
- matching: Option<uint>,
- matches_so_far: &mut Vec<(uint, P<ast::Variant>,
- Vec<(Span, Option<Ident>, Gc<Expr>)>)> ,
- match_count: uint) -> Gc<Expr> {
- if match_count == self_args.len() {
- // we've matched against all arguments, so make the final
- // expression at the bottom of the match tree
- if matches_so_far.len() == 0 {
- cx.span_bug(trait_.span,
- "no self match on an enum in \
- generic `deriving`");
- }
-
- // `ref` inside let matches is buggy. Causes havoc with rusc.
- // let (variant_index, ref self_vec) = matches_so_far[0];
- let (variant, self_vec) = match matches_so_far.get(0) {
- &(_, v, ref s) => (v, s)
- };
-
- // we currently have a vec of vecs, where each
- // subvec is the fields of one of the arguments,
- // but if the variants all match, we want this as
- // vec of tuples, where each tuple represents a
- // field.
-
- // most arms don't have matching variants, so do a
- // quick check to see if they match (even though
- // this means iterating twice) instead of being
- // optimistic and doing a pile of allocations etc.
- let substructure = match matching {
- Some(variant_index) => {
- let mut enum_matching_fields = Vec::from_elem(self_vec.len(), Vec::new());
-
- for triple in matches_so_far.tail().iter() {
- match triple {
- &(_, _, ref other_fields) => {
- for (i, &(_, _, e)) in other_fields.iter().enumerate() {
- enum_matching_fields.get_mut(i).push(e);
- }
- }
- }
- }
- let field_tuples =
- self_vec.iter()
- .zip(enum_matching_fields.iter())
- .map(|(&(span, id, self_f), other)| {
- FieldInfo {
- span: span,
- name: id,
- self_: self_f,
- other: (*other).clone()
- }
- }).collect();
- EnumMatching(variant_index, &*variant, field_tuples)
- }
- None => {
- EnumNonMatching(matches_so_far.as_slice())
+ fn build_enum_match_tuple(
+ &self,
+ cx: &mut ExtCtxt,
+ trait_: &TraitDef,
+ enum_def: &EnumDef,
+ type_ident: Ident,
+ self_args: &[Gc<Expr>],
+ nonself_args: &[Gc<Expr>]) -> Gc<Expr> {
+
+ let sp = trait_.span;
+ let variants = &enum_def.variants;
+
+ let self_arg_names = self_args.iter().enumerate()
+ .map(|(arg_count, _self_arg)| {
+ if arg_count == 0 {
+ "__self".to_string()
+ } else {
+ format!("__arg_{}", arg_count)
}
- };
- self.call_substructure_method(cx, trait_, type_ident,
- self_args, nonself_args,
- &substructure)
+ })
+ .collect::<Vec<String>>();
+
+ let self_arg_idents = self_arg_names.iter()
+ .map(|name|cx.ident_of(name.as_slice()))
+ .collect::<Vec<ast::Ident>>();
+
+ // The `vi_idents` will be bound, solely in the catch-all, to
+ // a series of let statements mapping each self_arg to a uint
+ // corresponding to its variant index.
+ let vi_idents : Vec<ast::Ident> = self_arg_names.iter()
+ .map(|name| { let vi_suffix = format!("{:s}_vi", name.as_slice());
+ cx.ident_of(vi_suffix.as_slice()) })
+ .collect::<Vec<ast::Ident>>();
+
+ // Builds, via callback to call_substructure_method, the
+ // delegated expression that handles the catch-all case,
+ // using `__variants_tuple` to drive logic if necessary.
+ let catch_all_substructure = EnumNonMatchingCollapsed(
+ self_arg_idents, variants.as_slice(), vi_idents.as_slice());
+
+ // These arms are of the form:
+ // (Variant1, Variant1, ...) => Body1
+ // (Variant2, Variant2, ...) => Body2
+ // ...
+ // where each tuple has length = self_args.len()
+ let mut match_arms : Vec<ast::Arm> = variants.iter().enumerate()
+ .map(|(index, &variant)| {
+
+ // These self_pats have form Variant1, Variant2, ...
+ let self_pats : Vec<(Gc<ast::Pat>,
+ Vec<(Span, Option<Ident>, Gc<Expr>)>)>;
+ self_pats = self_arg_names.iter()
+ .map(|self_arg_name|
+ trait_.create_enum_variant_pattern(
+ cx, &*variant, self_arg_name.as_slice(),
+ ast::MutImmutable))
+ .collect();
+
+ // A single arm has form (&VariantK, &VariantK, ...) => BodyK
+ // (see "Final wrinkle" note below for why.)
+ let subpats = self_pats.iter()
+ .map(|&(p, ref _idents)| cx.pat(sp, ast::PatRegion(p)))
+ .collect::<Vec<Gc<ast::Pat>>>();
+
+ // Here is the pat = `(&VariantK, &VariantK, ...)`
+ let single_pat = cx.pat(sp, ast::PatTup(subpats));
+
+ // For the BodyK, we need to delegate to our caller,
+ // passing it an EnumMatching to indicate which case
+ // we are in.
+
+ // All of the Self args have the same variant in these
+ // cases. So we transpose the info in self_pats to
+ // gather the getter expressions together, in the form
+ // that EnumMatching expects.
+
+ // The transposition is driven by walking across the
+ // arg fields of the variant for the first self pat.
+ let &(_, ref self_arg_fields) = self_pats.get(0);
+
+ let field_tuples : Vec<FieldInfo>;
+
+ field_tuples = self_arg_fields.iter().enumerate()
+ // For each arg field of self, pull out its getter expr ...
+ .map(|(field_index, &(sp, opt_ident, self_getter_expr))| {
+ // ... but FieldInfo also wants getter expr
+ // for matching other arguments of Self type;
+ // so walk across the *other* self_pats and
+ // pull out getter for same field in each of
+ // them (using `field_index` tracked above).
+ // That is the heart of the transposition.
+ let others = self_pats.tail().iter()
+ .map(|&(_pat, ref fields)| {
+
+ let &(_, _opt_ident, other_getter_expr) =
+ fields.get(field_index);
+
+ // All Self args have same variant, so
+ // opt_idents are the same. (Assert
+ // here to make it self-evident that
+ // it is okay to ignore `_opt_ident`.)
+ assert!(opt_ident == _opt_ident);
+
+ other_getter_expr
+ }).collect::<Vec<Gc<Expr>>>();
+
+ FieldInfo { span: sp,
+ name: opt_ident,
+ self_: self_getter_expr,
+ other: others,
+ }
+ }).collect::<Vec<FieldInfo>>();
+
+ // Now, for some given VariantK, we have built up
+ // expressions for referencing every field of every
+ // Self arg, assuming all are instances of VariantK.
+ // Build up code associated with such a case.
+ let substructure = EnumMatching(index, variant, field_tuples);
+ let arm_expr = self.call_substructure_method(
+ cx, trait_, type_ident, self_args, nonself_args,
+ &substructure);
+
+ cx.arm(sp, vec![single_pat], arm_expr)
+ }).collect();
- } else { // there are still matches to create
- let current_match_str = if match_count == 0 {
- "__self".to_string()
- } else {
- format!("__arg_{}", match_count)
- };
+ // We will usually need the catch-all after matching the
+ // tuples `(VariantK, VariantK, ...)` for each VariantK of the
+ // enum. But:
+ //
+ // * when there is only one Self arg, the arms above suffice
+ // (and the deriving we call back into may not be prepared to
+ // handle EnumNonMatchCollapsed), and,
+ //
+ // * when the enum has only one variant, the single arm that
+ // is already present always suffices.
+ //
+ // * In either of the two cases above, if we *did* add a
+ // catch-all `_` match, it would trigger the
+ // unreachable-pattern error.
+ //
+ if variants.len() > 1 && self_args.len() > 1 {
+ let arms : Vec<ast::Arm> = variants.iter().enumerate()
+ .map(|(index, &variant)| {
+ let pat = variant_to_pat(cx, sp, &*variant);
+ let lit = ast::LitUint(index as u64, ast::TyU);
+ cx.arm(sp, vec![pat], cx.expr_lit(sp, lit))
+ }).collect();
- let mut arms = Vec::new();
-
- // the code for nonmatching variants only matters when
- // we've seen at least one other variant already
- if self.const_nonmatching && match_count > 0 {
- // make a matching-variant match, and a _ match.
- let index = match matching {
- Some(i) => i,
- None => cx.span_bug(trait_.span,
- "non-matching variants when required to \
- be matching in generic `deriving`")
- };
-
- // matching-variant match
- let variant = *enum_def.variants.get(index);
- let (pattern, idents) = trait_.create_enum_variant_pattern(
- cx,
- &*variant,
- current_match_str.as_slice(),
- ast::MutImmutable);
-
- matches_so_far.push((index, variant, idents));
- let arm_expr = self.build_enum_match(cx,
- trait_,
- enum_def,
- type_ident,
- self_args, nonself_args,
- matching,
- matches_so_far,
- match_count + 1);
- matches_so_far.pop().unwrap();
- arms.push(cx.arm(trait_.span, vec!( pattern ), arm_expr));
-
- if enum_def.variants.len() > 1 {
- let e = &EnumNonMatching(&[]);
- let wild_expr = self.call_substructure_method(cx, trait_, type_ident,
- self_args, nonself_args,
- e);
- let wild_arm = cx.arm(
- trait_.span,
- vec!( cx.pat_wild(trait_.span) ),
- wild_expr);
- arms.push(wild_arm);
- }
- } else {
- // create an arm matching on each variant
- for (index, &variant) in enum_def.variants.iter().enumerate() {
- let (pattern, idents) =
- trait_.create_enum_variant_pattern(
- cx,
- &*variant,
- current_match_str.as_slice(),
- ast::MutImmutable);
-
- matches_so_far.push((index, variant, idents));
- let new_matching =
- match matching {
- _ if match_count == 0 => Some(index),
- Some(i) if index == i => Some(i),
- _ => None
- };
- let arm_expr = self.build_enum_match(cx,
- trait_,
- enum_def,
- type_ident,
- self_args, nonself_args,
- new_matching,
- matches_so_far,
- match_count + 1);
- matches_so_far.pop().unwrap();
-
- let arm = cx.arm(trait_.span, vec!( pattern ), arm_expr);
- arms.push(arm);
- }
+ // Build a series of let statements mapping each self_arg
+ // to a uint corresponding to its variant index.
+ // i.e. for `enum E<T> { A, B(1), C(T, T) }`, and a deriving
+ // with three Self args, builds three statements:
+ //
+ // ```
+ // let __self0_vi = match self {
+ // A => 0u, B(..) => 1u, C(..) => 2u
+ // };
+ // let __self1_vi = match __arg1 {
+ // A => 0u, B(..) => 1u, C(..) => 2u
+ // };
+ // let __self2_vi = match __arg2 {
+ // A => 0u, B(..) => 1u, C(..) => 2u
+ // };
+ // ```
+ let mut index_let_stmts : Vec<Gc<ast::Stmt>> = Vec::new();
+ for (&ident, &self_arg) in vi_idents.iter().zip(self_args.iter()) {
+ let variant_idx = cx.expr_match(sp, self_arg, arms.clone());
+ let let_stmt = cx.stmt_let(sp, false, ident, variant_idx);
+ index_let_stmts.push(let_stmt);
}
- // match foo { arm, arm, arm, ... }
- cx.expr_match(trait_.span, self_args[match_count], arms)
+ let arm_expr = self.call_substructure_method(
+ cx, trait_, type_ident, self_args, nonself_args,
+ &catch_all_substructure);
+
+ // Builds the expression:
+ // {
+ // let __self0_vi = ...;
+ // let __self1_vi = ...;
+ // ...
+ // <delegated expression referring to __self0_vi, et al.>
+ // }
+ let arm_expr = cx.expr_block(
+ cx.block_all(sp, Vec::new(), index_let_stmts, Some(arm_expr)));
+
+ // Builds arm:
+ // _ => { let __self0_vi = ...;
+ // let __self1_vi = ...;
+ // ...
+ // <delegated expression as above> }
+ let catch_all_match_arm =
+ cx.arm(sp, vec![cx.pat_wild(sp)], arm_expr);
+
+ match_arms.push(catch_all_match_arm);
+
+ } else if variants.len() == 0 {
+ // As an additional wrinkle, For a zero-variant enum A,
+ // currently the compiler
+ // will accept `fn (a: &Self) { match *a { } }`
+ // but rejects `fn (a: &Self) { match (&*a,) { } }`
+ // as well as `fn (a: &Self) { match ( *a,) { } }`
+ //
+ // This means that the strategy of building up a tuple of
+ // all Self arguments fails when Self is a zero variant
+ // enum: rustc rejects the expanded program, even though
+ // the actual code tends to be impossible to execute (at
+ // least safely), according to the type system.
+ //
+ // The most expedient fix for this is to just let the
+ // code fall through to the catch-all. But even this is
+ // error-prone, since the catch-all as defined above would
+ // generate code like this:
+ //
+ // _ => { let __self0 = match *self { };
+ // let __self1 = match *__arg_0 { };
+ // <catch-all-expr> }
+ //
+ // Which is yields bindings for variables which type
+ // inference cannot resolve to unique types.
+ //
+ // One option to the above might be to add explicit type
+ // annotations. But the *only* reason to go down that path
+ // would be to try to make the expanded output consistent
+ // with the case when the number of enum variants >= 1.
+ //
+ // That just isn't worth it. In fact, trying to generate
+ // sensible code for *any* deriving on a zero-variant enum
+ // does not make sense. But at the same time, for now, we
+ // do not want to cause a compile failure just because the
+ // user happened to attach a deriving to their
+ // zero-variant enum.
+ //
+ // Instead, just generate a failing expression for the
+ // zero variant case, skipping matches and also skipping
+ // delegating back to the end user code entirely.
+ //
+ // (See also #4499 and #12609; note that some of the
+ // discussions there influence what choice we make here;
+ // e.g. if we feature-gate `match x { ... }` when x refers
+ // to an uninhabited type (e.g. a zero-variant enum or a
+ // type holding such an enum), but do not feature-gate
+ // zero-variant enums themselves, then attempting to
+ // derive Show on such a type could here generate code
+ // that needs the feature gate enabled.)
+
+ return cx.expr_unreachable(sp);
}
+
+ // Final wrinkle: the self_args are expressions that deref
+ // down to desired l-values, but we cannot actually deref
+ // them when they are fed as r-values into a tuple
+ // expression; here add a layer of borrowing, turning
+ // `(*self, *__arg_0, ...)` into `(&*self, &*__arg_0, ...)`.
+ let borrowed_self_args = self_args.iter()
+ .map(|&self_arg| cx.expr_addr_of(sp, self_arg))
+ .collect::<Vec<Gc<ast::Expr>>>();
+ let match_arg = cx.expr(sp, ast::ExprTup(borrowed_self_args));
+ cx.expr_match(sp, match_arg, match_arms)
}
fn expand_static_enum_method_body(&self,
pub fn cs_fold(use_foldl: bool,
f: |&mut ExtCtxt, Span, Gc<Expr>, Gc<Expr>, &[Gc<Expr>]| -> Gc<Expr>,
base: Gc<Expr>,
- enum_nonmatch_f: EnumNonMatchFunc,
+ enum_nonmatch_f: EnumNonMatchCollapsedFunc,
cx: &mut ExtCtxt,
trait_span: Span,
substructure: &Substructure)
})
}
},
- EnumNonMatching(ref all_enums) => enum_nonmatch_f(cx, trait_span,
- *all_enums,
- substructure.nonself_args),
+ EnumNonMatchingCollapsed(ref all_args, _, tuple) =>
+ enum_nonmatch_f(cx, trait_span, (all_args.as_slice(), tuple),
+ substructure.nonself_args),
StaticEnum(..) | StaticStruct(..) => {
cx.span_bug(trait_span, "static function in `deriving`")
}
*/
#[inline]
pub fn cs_same_method(f: |&mut ExtCtxt, Span, Vec<Gc<Expr>>| -> Gc<Expr>,
- enum_nonmatch_f: EnumNonMatchFunc,
+ enum_nonmatch_f: EnumNonMatchCollapsedFunc,
cx: &mut ExtCtxt,
trait_span: Span,
substructure: &Substructure)
f(cx, trait_span, called)
},
- EnumNonMatching(ref all_enums) => enum_nonmatch_f(cx, trait_span,
- *all_enums,
- substructure.nonself_args),
+ EnumNonMatchingCollapsed(ref all_self_args, _, tuple) =>
+ enum_nonmatch_f(cx, trait_span, (all_self_args.as_slice(), tuple),
+ substructure.nonself_args),
StaticEnum(..) | StaticStruct(..) => {
cx.span_bug(trait_span, "static function in `deriving`")
}
pub fn cs_same_method_fold(use_foldl: bool,
f: |&mut ExtCtxt, Span, Gc<Expr>, Gc<Expr>| -> Gc<Expr>,
base: Gc<Expr>,
- enum_nonmatch_f: EnumNonMatchFunc,
+ enum_nonmatch_f: EnumNonMatchCollapsedFunc,
cx: &mut ExtCtxt,
trait_span: Span,
substructure: &Substructure)
*/
#[inline]
pub fn cs_binop(binop: ast::BinOp, base: Gc<Expr>,
- enum_nonmatch_f: EnumNonMatchFunc,
+ enum_nonmatch_f: EnumNonMatchCollapsedFunc,
cx: &mut ExtCtxt, trait_span: Span,
substructure: &Substructure) -> Gc<Expr> {
cs_same_method_fold(
/// cs_binop with binop == or
#[inline]
-pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
+pub fn cs_or(enum_nonmatch_f: EnumNonMatchCollapsedFunc,
cx: &mut ExtCtxt, span: Span,
substructure: &Substructure) -> Gc<Expr> {
cs_binop(ast::BiOr, cx.expr_bool(span, false),
/// cs_binop with binop == and
#[inline]
-pub fn cs_and(enum_nonmatch_f: EnumNonMatchFunc,
+pub fn cs_and(enum_nonmatch_f: EnumNonMatchCollapsedFunc,
cx: &mut ExtCtxt, span: Span,
substructure: &Substructure) -> Gc<Expr> {
cs_binop(ast::BiAnd, cx.expr_bool(span, true),
use ext::build::AstBuilder;
use codemap::{Span,respan};
use owned_slice::OwnedSlice;
+use parse::token::special_idents;
use std::gc::Gc;
/// The types of pointers
pub enum PtrTy<'a> {
- Send, // ~
- Borrowed(Option<&'a str>, ast::Mutability), // &['lifetime] [mut]
+ /// ~
+ Send,
+ /// &'lifetime mut
+ Borrowed(Option<&'a str>, ast::Mutability),
}
/// A path, e.g. `::std::option::Option::<int>` (global). Has support
/// A type. Supports pointers (except for *), Self, and literals
pub enum Ty<'a> {
Self,
- // &/Box/ Ty
+ /// &/Box/ Ty
Ptr(Box<Ty<'a>>, PtrTy<'a>),
- // mod::mod::Type<[lifetime], [Params...]>, including a plain type
- // parameter, and things like `int`
+ /// mod::mod::Type<[lifetime], [Params...]>, including a plain type
+ /// parameter, and things like `int`
Literal(Path<'a>),
- // includes nil
+ /// includes unit
Tuple(Vec<Ty<'a>> )
}
}
-fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str, sized: ast::Sized, bounds: &[Path],
+fn mk_ty_param(cx: &ExtCtxt, span: Span, name: &str,
+ bounds: &[Path], unbound: Option<ast::TyParamBound>,
self_ident: Ident, self_generics: &Generics) -> ast::TyParam {
let bounds =
bounds.iter().map(|b| {
let path = b.to_path(cx, span, self_ident, self_generics);
cx.typarambound(path)
}).collect();
- cx.typaram(span, cx.ident_of(name), sized, bounds, None)
+ cx.typaram(span, cx.ident_of(name), bounds, unbound, None)
}
-fn mk_generics(lifetimes: Vec<ast::Lifetime> , ty_params: Vec<ast::TyParam> ) -> Generics {
+fn mk_generics(lifetimes: Vec<ast::Lifetime>, ty_params: Vec<ast::TyParam> ) -> Generics {
Generics {
lifetimes: lifetimes,
ty_params: OwnedSlice::from_vec(ty_params)
/// Lifetimes and bounds on type parameters
pub struct LifetimeBounds<'a> {
pub lifetimes: Vec<&'a str>,
- pub bounds: Vec<(&'a str, ast::Sized, Vec<Path<'a>>)>,
+ pub bounds: Vec<(&'a str, Option<ast::TyParamBound>, Vec<Path<'a>>)>,
}
impl<'a> LifetimeBounds<'a> {
}).collect();
let ty_params = self.bounds.iter().map(|t| {
match t {
- &(ref name, sized, ref bounds) => {
+ &(ref name, ref unbound, ref bounds) => {
mk_ty_param(cx,
span,
*name,
- sized,
bounds.as_slice(),
+ unbound.clone(),
self_ty,
self_generics)
}
}
}
-
pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
-> (Gc<Expr>, ast::ExplicitSelf) {
+ // this constructs a fresh `self` path, which will match the fresh `self` binding
+ // created below.
let self_path = cx.expr_self(span);
match *self_ptr {
None => {
- (self_path, respan(span, ast::SelfValue))
+ (self_path, respan(span, ast::SelfValue(special_idents::self_)))
}
Some(ref ptr) => {
let self_ty = respan(
span,
match *ptr {
- Send => ast::SelfUniq,
+ Send => ast::SelfUniq(special_idents::self_),
Borrowed(ref lt, mutbl) => {
let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s).name));
- ast::SelfRegion(lt, mutbl)
+ ast::SelfRegion(lt, mutbl, special_idents::self_)
}
});
let self_expr = cx.expr_deref(span, self_path);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use ast;
use ast::{MetaItem, Item, Expr, MutMutable};
use codemap::Span;
use ext::base::ExtCtxt;
vec!(box Literal(Path::new_local("__S"))), true),
LifetimeBounds {
lifetimes: Vec::new(),
- bounds: vec!(("__S", ast::StaticSize,
+ bounds: vec!(("__S", None,
vec!(Path::new(vec!("std", "hash", "Writer"))))),
},
Path::new_local("__S"))
args: vec!(Ptr(box Literal(args), Borrowed(None, MutMutable))),
ret_ty: nil_ty(),
attributes: attrs,
- const_nonmatching: false,
combine_substructure: combine_substructure(|a, b, c| {
hash_substructure(a, b, c)
})
true)),
// #[inline] liable to cause code-bloat
attributes: attrs.clone(),
- const_nonmatching: false,
combine_substructure: combine_substructure(|c, s, sub| {
cs_from("i64", c, s, sub)
}),
true)),
// #[inline] liable to cause code-bloat
attributes: attrs,
- const_nonmatching: false,
combine_substructure: combine_substructure(|c, s, sub| {
cs_from("u64", c, s, sub)
}),
generics: LifetimeBounds {
lifetimes: Vec::new(),
bounds: vec!(("R",
- ast::StaticSize,
+ None,
vec!( Path::new(vec!("std", "rand", "Rng")) )))
},
explicit_self: None,
),
ret_ty: Self,
attributes: Vec::new(),
- const_nonmatching: false,
combine_substructure: combine_substructure(|a, b, c| {
rand_substructure(a, b, c)
})
args: vec!(fmtr),
ret_ty: Literal(Path::new(vec!("std", "fmt", "Result"))),
attributes: Vec::new(),
- const_nonmatching: false,
combine_substructure: combine_substructure(|a, b, c| {
show_substructure(a, b, c)
})
trait_def.expand(cx, mitem, item, push)
}
-// we construct a format string and then defer to std::fmt, since that
-// knows what's up with formatting at so on.
+/// We construct a format string and then defer to std::fmt, since that
+/// knows what's up with formatting and so on.
fn show_substructure(cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> Gc<Expr> {
// build `<name>`, `<name>({}, {}, ...)` or `<name> { <field>: {},
let name = match *substr.fields {
Struct(_) => substr.type_ident,
EnumMatching(_, v, _) => v.node.name,
-
- EnumNonMatching(..) | StaticStruct(..) | StaticEnum(..) => {
+ EnumNonMatchingCollapsed(..) | StaticStruct(..) | StaticEnum(..) => {
cx.span_bug(span, "nonsensical .fields in `#[deriving(Show)]`")
}
};
args: Vec::new(),
ret_ty: Self,
attributes: attrs.clone(),
- const_nonmatching: false,
combine_substructure: combine_substructure(|a, b, c| {
zero_substructure(a, b, c)
})
args: Vec::new(),
ret_ty: Literal(Path::new(vec!("bool"))),
attributes: attrs,
- const_nonmatching: false,
combine_substructure: combine_substructure(|cx, span, substr| {
cs_and(|cx, span, _, _| cx.span_bug(span,
"Non-matching enum \
Some(exprs) => exprs
};
- let var = match expr_to_str(cx,
+ let var = match expr_to_string(cx,
*exprs.get(0),
"expected string literal") {
None => return DummyResult::expr(sp),
var).as_slice())
}
2 => {
- match expr_to_str(cx, *exprs.get(1), "expected string literal") {
+ match expr_to_string(cx, *exprs.get(1), "expected string literal") {
None => return DummyResult::expr(sp),
Some((s, _style)) => s
}
use attr::AttrMetaMethods;
use codemap;
use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
-use crateid::CrateId;
use ext::base::*;
+use fold;
use fold::*;
use parse;
use parse::token::{fresh_mark, fresh_name, intern};
// expr_mac should really be expr_ext or something; it's the
// entry-point for all syntax extensions.
ExprMac(ref mac) => {
- match (*mac).node {
- // it would almost certainly be cleaner to pass the whole
- // macro invocation in, rather than pulling it apart and
- // marking the tts and the ctxt separately. This also goes
- // for the other three macro invocation chunks of code
- // in this file.
- // Token-tree macros:
- MacInvocTT(ref pth, ref tts, _) => {
- if pth.segments.len() > 1u {
- fld.cx.span_err(pth.span,
- "expected macro name without module \
- separators");
- // let compilation continue
- return DummyResult::raw_expr(e.span);
- }
- let extname = pth.segments.get(0).identifier;
- let extnamestr = token::get_ident(extname);
- let marked_after = match fld.extsbox.find(&extname.name) {
- None => {
- fld.cx.span_err(
- pth.span,
- format!("macro undefined: '{}'",
- extnamestr.get()).as_slice());
-
- // let compilation continue
- return DummyResult::raw_expr(e.span);
- }
- Some(&NormalTT(ref expandfun, exp_span)) => {
- fld.cx.bt_push(ExpnInfo {
- call_site: e.span,
- callee: NameAndSpan {
- name: extnamestr.get().to_string(),
- format: MacroBang,
- span: exp_span,
- },
- });
- let fm = fresh_mark();
- // mark before:
- let marked_before = mark_tts(tts.as_slice(), fm);
-
- // The span that we pass to the expanders we want to
- // be the root of the call stack. That's the most
- // relevant span and it's the actual invocation of
- // the macro.
- let mac_span = original_span(fld.cx);
-
- let expanded = match expandfun.expand(fld.cx,
- mac_span.call_site,
- marked_before.as_slice()).make_expr() {
- Some(e) => e,
- None => {
- fld.cx.span_err(
- pth.span,
- format!("non-expression macro in expression position: {}",
- extnamestr.get().as_slice()
- ).as_slice());
- return DummyResult::raw_expr(e.span);
- }
- };
+ let expanded_expr = match expand_mac_invoc(mac,&e.span,
+ |r|{r.make_expr()},
+ |expr,fm|{mark_expr(expr,fm)},
+ fld) {
+ Some(expr) => expr,
+ None => {
+ return DummyResult::raw_expr(e.span);
+ }
+ };
- // mark after:
- mark_expr(expanded,fm)
- }
- _ => {
- fld.cx.span_err(
- pth.span,
- format!("'{}' is not a tt-style macro",
- extnamestr.get()).as_slice());
- return DummyResult::raw_expr(e.span);
- }
- };
+ // Keep going, outside-in.
+ //
+ // FIXME(pcwalton): Is it necessary to clone the
+ // node here?
+ let fully_expanded =
+ fld.fold_expr(expanded_expr).node.clone();
+ fld.cx.bt_pop();
- // Keep going, outside-in.
- //
- // FIXME(pcwalton): Is it necessary to clone the
- // node here?
- let fully_expanded =
- fld.fold_expr(marked_after).node.clone();
- fld.cx.bt_pop();
-
- box(GC) ast::Expr {
- id: ast::DUMMY_NODE_ID,
- node: fully_expanded,
- span: e.span,
- }
- }
+ box(GC) ast::Expr {
+ id: ast::DUMMY_NODE_ID,
+ node: fully_expanded,
+ span: e.span,
}
}
fld.cx.expr(e.span, ast::ExprLoop(loop_block, opt_ident))
}
+ ast::ExprFnBlock(fn_decl, block) => {
+ let (rewritten_fn_decl, rewritten_block)
+ = expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
+ let new_node = ast::ExprFnBlock(rewritten_fn_decl, rewritten_block);
+ box(GC) ast::Expr{id:e.id, node: new_node, span: fld.new_span(e.span)}
+ }
+
+ ast::ExprProc(fn_decl, block) => {
+ let (rewritten_fn_decl, rewritten_block)
+ = expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
+ let new_node = ast::ExprProc(rewritten_fn_decl, rewritten_block);
+ box(GC) ast::Expr{id:e.id, node: new_node, span: fld.new_span(e.span)}
+ }
+
_ => noop_fold_expr(e, fld)
}
}
-// Rename loop label and expand its loop body
-//
-// The renaming procedure for loop is different in the sense that the loop
-// body is in a block enclosed by loop head so the renaming of loop label
-// must be propagated to the enclosed context.
+/// Expand a (not-ident-style) macro invocation. Returns the result
+/// of expansion and the mark which must be applied to the result.
+/// Our current interface doesn't allow us to apply the mark to the
+/// result until after calling make_expr, make_items, etc.
+fn expand_mac_invoc<T>(mac: &ast::Mac, span: &codemap::Span,
+ parse_thunk: |Box<MacResult>|->Option<T>,
+ mark_thunk: |T,Mrk|->T,
+ fld: &mut MacroExpander)
+ -> Option<T> {
+ match (*mac).node {
+ // it would almost certainly be cleaner to pass the whole
+ // macro invocation in, rather than pulling it apart and
+ // marking the tts and the ctxt separately. This also goes
+ // for the other three macro invocation chunks of code
+ // in this file.
+ // Token-tree macros:
+ MacInvocTT(ref pth, ref tts, _) => {
+ if pth.segments.len() > 1u {
+ fld.cx.span_err(pth.span,
+ "expected macro name without module \
+ separators");
+ // let compilation continue
+ return None;
+ }
+ let extname = pth.segments.get(0).identifier;
+ let extnamestr = token::get_ident(extname);
+ match fld.extsbox.find(&extname.name) {
+ None => {
+ fld.cx.span_err(
+ pth.span,
+ format!("macro undefined: '{}!'",
+ extnamestr.get()).as_slice());
+
+ // let compilation continue
+ None
+ }
+ Some(&NormalTT(ref expandfun, exp_span)) => {
+ fld.cx.bt_push(ExpnInfo {
+ call_site: *span,
+ callee: NameAndSpan {
+ name: extnamestr.get().to_string(),
+ format: MacroBang,
+ span: exp_span,
+ },
+ });
+ let fm = fresh_mark();
+ let marked_before = mark_tts(tts.as_slice(), fm);
+
+ // The span that we pass to the expanders we want to
+ // be the root of the call stack. That's the most
+ // relevant span and it's the actual invocation of
+ // the macro.
+ let mac_span = original_span(fld.cx);
+
+ let expanded = expandfun.expand(fld.cx,
+ mac_span.call_site,
+ marked_before.as_slice());
+ let parsed = match parse_thunk(expanded) {
+ Some(e) => e,
+ None => {
+ fld.cx.span_err(
+ pth.span,
+ format!("non-expression macro in expression position: {}",
+ extnamestr.get().as_slice()
+ ).as_slice());
+ return None;
+ }
+ };
+ Some(mark_thunk(parsed,fm))
+ }
+ _ => {
+ fld.cx.span_err(
+ pth.span,
+ format!("'{}' is not a tt-style macro",
+ extnamestr.get()).as_slice());
+ None
+ }
+ }
+ }
+ }
+}
+
+/// Rename loop label and expand its loop body
+///
+/// The renaming procedure for loop is different in the sense that the loop
+/// body is in a block enclosed by loop head so the renaming of loop label
+/// must be propagated to the enclosed context.
fn expand_loop_block(loop_block: P<Block>,
opt_ident: Option<Ident>,
fld: &mut MacroExpander) -> (P<Block>, Option<Ident>) {
}
}
-// eval $e with a new exts frame:
+// eval $e with a new exts frame.
+// must be a macro so that $e isn't evaluated too early.
macro_rules! with_exts_frame (
($extsboxexpr:expr,$macros_escape:expr,$e:expr) =>
({$extsboxexpr.push_frame();
fn expand_item_modifiers(mut it: Gc<ast::Item>, fld: &mut MacroExpander)
-> Gc<ast::Item> {
- let (modifiers, attrs) = it.attrs.partitioned(|attr| {
+ // partition the attributes into ItemModifiers and others
+ let (modifiers, other_attrs) = it.attrs.partitioned(|attr| {
match fld.extsbox.find(&intern(attr.name().get())) {
Some(&ItemModifier(_)) => true,
_ => false
}
});
-
+ // update the attrs, leave everything else alone. Is this mutation really a good idea?
it = box(GC) ast::Item {
- attrs: attrs,
+ attrs: other_attrs,
..(*it).clone()
};
expand_item_modifiers(it, fld)
}
+/// Expand item_underscore
+fn expand_item_underscore(item: &ast::Item_, fld: &mut MacroExpander) -> ast::Item_ {
+ match *item {
+ ast::ItemFn(decl, fn_style, abi, ref generics, body) => {
+ let (rewritten_fn_decl, rewritten_body)
+ = expand_and_rename_fn_decl_and_block(decl,body,fld);
+ let expanded_generics = fold::fold_generics(generics,fld);
+ ast::ItemFn(rewritten_fn_decl, fn_style, abi, expanded_generics, rewritten_body)
+ }
+ _ => noop_fold_item_underscore(&*item, fld)
+ }
+}
+
// does this attribute list contain "macro_escape" ?
fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool {
attr::contains_name(attrs, "macro_escape")
let marked_tts = mark_tts(tts.as_slice(), fm);
expander.expand(fld.cx, it.span, it.ident, marked_tts)
}
+ Some(&LetSyntaxTT(ref expander, span)) => {
+ if it.ident.name == parse::token::special_idents::invalid.name {
+ fld.cx.span_err(pth.span,
+ format!("macro {}! expects an ident argument",
+ extnamestr.get()).as_slice());
+ return SmallVector::zero();
+ }
+ fld.cx.bt_push(ExpnInfo {
+ call_site: it.span,
+ callee: NameAndSpan {
+ name: extnamestr.get().to_string(),
+ format: MacroBang,
+ span: span
+ }
+ });
+ // DON'T mark before expansion:
+ expander.expand(fld.cx, it.span, it.ident, tts)
+ }
_ => {
fld.cx.span_err(it.span,
format!("{}! is not legal in item position",
let items = match expanded.make_def() {
Some(MacroDef { name, ext }) => {
- // yikes... no idea how to apply the mark to this. I'm afraid
- // we're going to have to wait-and-see on this one.
+ // hidden invariant: this should only be possible as the
+ // result of expanding a LetSyntaxTT, and thus doesn't
+ // need to be marked. Not that it could be marked anyway.
+ // create issue to recommend refactoring here?
fld.extsbox.insert(intern(name.as_slice()), ext);
if attr::contains_name(it.attrs.as_slice(), "macro_export") {
- SmallVector::one(it)
- } else {
- SmallVector::zero()
+ fld.cx.push_exported_macro(it.span);
}
+ SmallVector::zero()
}
None => {
match expanded.make_items() {
Some(items) => {
items.move_iter()
- .flat_map(|i| mark_item(i, fm).move_iter())
+ .map(|i| mark_item(i, fm))
.flat_map(|i| fld.fold_item(i).move_iter())
.collect()
}
return items;
}
-// expand a stmt
+/// Expand a stmt
+//
+// I don't understand why this returns a vector... it looks like we're
+// half done adding machinery to allow macros to expand into multiple statements.
fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<Gc<Stmt>> {
- // why the copying here and not in expand_expr?
- // looks like classic changed-in-only-one-place
- let (pth, tts, semi) = match s.node {
- StmtMac(ref mac, semi) => {
- match mac.node {
- MacInvocTT(ref pth, ref tts, _) => {
- (pth, (*tts).clone(), semi)
- }
- }
- }
+ let (mac, semi) = match s.node {
+ StmtMac(ref mac, semi) => (mac, semi),
_ => return expand_non_macro_stmt(s, fld)
};
- if pth.segments.len() > 1u {
- fld.cx.span_err(pth.span, "expected macro name without module separators");
- return SmallVector::zero();
- }
- let extname = pth.segments.get(0).identifier;
- let extnamestr = token::get_ident(extname);
- let marked_after = match fld.extsbox.find(&extname.name) {
+ let expanded_stmt = match expand_mac_invoc(mac,&s.span,
+ |r|{r.make_stmt()},
+ |sts,mrk|{mark_stmt(sts,mrk)},
+ fld) {
+ Some(stmt) => stmt,
None => {
- fld.cx.span_err(pth.span,
- format!("macro undefined: '{}'",
- extnamestr).as_slice());
- return SmallVector::zero();
- }
-
- Some(&NormalTT(ref expandfun, exp_span)) => {
- fld.cx.bt_push(ExpnInfo {
- call_site: s.span,
- callee: NameAndSpan {
- name: extnamestr.get().to_string(),
- format: MacroBang,
- span: exp_span,
- }
- });
- let fm = fresh_mark();
- // mark before expansion:
- let marked_tts = mark_tts(tts.as_slice(), fm);
-
- // See the comment in expand_expr for why we want the original span,
- // not the current mac.span.
- let mac_span = original_span(fld.cx);
-
- let expanded = match expandfun.expand(fld.cx,
- mac_span.call_site,
- marked_tts.as_slice()).make_stmt() {
- Some(stmt) => stmt,
- None => {
- fld.cx.span_err(pth.span,
- format!("non-statement macro in statement position: {}",
- extnamestr).as_slice());
- return SmallVector::zero();
- }
- };
-
- mark_stmt(&*expanded,fm)
- }
-
- _ => {
- fld.cx.span_err(pth.span, format!("'{}' is not a tt-style macro",
- extnamestr).as_slice());
return SmallVector::zero();
}
};
// Keep going, outside-in.
- let fully_expanded = fld.fold_stmt(&*marked_after);
- if fully_expanded.is_empty() {
- fld.cx.span_err(pth.span, "macro didn't expand to a statement");
- return SmallVector::zero();
- }
+ let fully_expanded = fld.fold_stmt(&*expanded_stmt);
fld.cx.bt_pop();
let fully_expanded: SmallVector<Gc<Stmt>> = fully_expanded.move_iter()
.map(|s| box(GC) Spanned { span: s.span, node: s.node.clone() })
} = **local;
// expand the pat (it might contain macro uses):
let expanded_pat = fld.fold_pat(pat);
- // find the pat_idents in the pattern:
+ // find the PatIdents in the pattern:
// oh dear heaven... this is going to include the enum
// names, as well... but that should be okay, as long as
// the new names are gensyms for the old ones.
}
}
+// expand the arm of a 'match', renaming for macro hygiene
fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
// expand pats... they might contain macro uses:
let expanded_pats : Vec<Gc<ast::Pat>> = arm.pats.iter().map(|pat| fld.fold_pat(*pat)).collect();
// all of the pats must have the same set of bindings, so use the
// first one to extract them and generate new names:
let first_pat = expanded_pats.get(0);
- // code duplicated from 'let', above. Perhaps this can be lifted
- // into a separate function:
let idents = pattern_bindings(*first_pat);
- let mut new_pending_renames =
+ let new_renames =
idents.iter().map(|id| (*id,fresh_name(id))).collect();
- // rewrite all of the patterns using the new names (the old
- // ones have already been applied). Note that we depend here
- // on the guarantee that after expansion, there can't be any
- // Path expressions (a.k.a. varrefs) left in the pattern. If
- // this were false, we'd need to apply this renaming only to
- // the bindings, and not to the varrefs, using a more targeted
- // fold-er.
- let mut rename_fld = IdentRenamer{renames:&mut new_pending_renames};
+ // apply the renaming, but only to the PatIdents:
+ let mut rename_pats_fld = PatIdentRenamer{renames:&new_renames};
let rewritten_pats =
- expanded_pats.iter().map(|pat| rename_fld.fold_pat(*pat)).collect();
+ expanded_pats.iter().map(|pat| rename_pats_fld.fold_pat(*pat)).collect();
// apply renaming and then expansion to the guard and the body:
+ let mut rename_fld = IdentRenamer{renames:&new_renames};
let rewritten_guard =
arm.guard.map(|g| fld.fold_expr(rename_fld.fold_expr(g)));
let rewritten_body = fld.fold_expr(rename_fld.fold_expr(arm.body));
}
}
-
-
-// a visitor that extracts the pat_ident (binding) paths
-// from a given thingy and puts them in a mutable
-// array
+/// A visitor that extracts the PatIdent (binding) paths
+/// from a given thingy and puts them in a mutable
+/// array
#[deriving(Clone)]
-struct NameFinderContext {
+struct PatIdentFinder {
ident_accumulator: Vec<ast::Ident> ,
}
-impl Visitor<()> for NameFinderContext {
+impl Visitor<()> for PatIdentFinder {
fn visit_pat(&mut self, pattern: &ast::Pat, _: ()) {
match *pattern {
- // we found a pat_ident!
- ast::Pat {
- id: _,
- node: ast::PatIdent(_, ref path1, ref inner),
- span: _
- } => {
+ ast::Pat { id: _, node: ast::PatIdent(_, ref path1, ref inner), span: _ } => {
self.ident_accumulator.push(path1.node);
- // visit optional subpattern of pat_ident:
+ // visit optional subpattern of PatIdent:
for subpat in inner.iter() {
self.visit_pat(&**subpat, ())
}
}
- // use the default traversal for non-pat_idents
+ // use the default traversal for non-PatIdents
_ => visit::walk_pat(self, pattern, ())
}
}
-
}
-// find the pat_ident paths in a pattern
+/// find the PatIdent paths in a pattern
fn pattern_bindings(pat : &ast::Pat) -> Vec<ast::Ident> {
- let mut name_finder = NameFinderContext{ident_accumulator:Vec::new()};
+ let mut name_finder = PatIdentFinder{ident_accumulator:Vec::new()};
name_finder.visit_pat(pat,());
name_finder.ident_accumulator
}
+/// find the PatIdent paths in a
+fn fn_decl_arg_bindings(fn_decl: &ast::FnDecl) -> Vec<ast::Ident> {
+ let mut pat_idents = PatIdentFinder{ident_accumulator:Vec::new()};
+ for arg in fn_decl.inputs.iter() {
+ pat_idents.visit_pat(arg.pat,());
+ }
+ pat_idents.ident_accumulator
+}
+
// expand a block. pushes a new exts_frame, then calls expand_block_elts
fn expand_block(blk: &Block, fld: &mut MacroExpander) -> P<Block> {
// see note below about treatment of exts table
}
}
-// a tree-folder that applies every rename in its (mutable) list
-// to every identifier, including both bindings and varrefs
-// (and lots of things that will turn out to be neither)
+/// A tree-folder that applies every rename in its (mutable) list
+/// to every identifier, including both bindings and varrefs
+/// (and lots of things that will turn out to be neither)
pub struct IdentRenamer<'a> {
- renames: &'a mut RenameList,
+ renames: &'a mtwt::RenameList,
}
impl<'a> Folder for IdentRenamer<'a> {
fn fold_ident(&mut self, id: Ident) -> Ident {
- let new_ctxt = self.renames.iter().fold(id.ctxt, |ctxt, &(from, to)| {
- mtwt::new_rename(from, to, ctxt)
- });
Ident {
name: id.name,
- ctxt: new_ctxt,
+ ctxt: mtwt::apply_renames(self.renames, id.ctxt),
}
}
+ fn fold_mac(&mut self, macro: &ast::Mac) -> ast::Mac {
+ fold::fold_mac(macro, self)
+ }
}
-fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
- /* this discards information in the case of macro-defining macros */
- Span {
- lo: sp.lo,
- hi: sp.hi,
- expn_info: cx.backtrace(),
+/// A tree-folder that applies every rename in its list to
+/// the idents that are in PatIdent patterns. This is more narrowly
+/// focused than IdentRenamer, and is needed for FnDecl,
+/// where we want to rename the args but not the fn name or the generics etc.
+pub struct PatIdentRenamer<'a> {
+ renames: &'a mtwt::RenameList,
+}
+
+impl<'a> Folder for PatIdentRenamer<'a> {
+ fn fold_pat(&mut self, pat: Gc<ast::Pat>) -> Gc<ast::Pat> {
+ match pat.node {
+ ast::PatIdent(binding_mode, Spanned{span: ref sp, node: id}, ref sub) => {
+ let new_ident = Ident{name: id.name,
+ ctxt: mtwt::apply_renames(self.renames, id.ctxt)};
+ let new_node =
+ ast::PatIdent(binding_mode,
+ Spanned{span: self.new_span(*sp), node: new_ident},
+ sub.map(|p| self.fold_pat(p)));
+ box(GC) ast::Pat {
+ id: pat.id,
+ span: self.new_span(pat.span),
+ node: new_node,
+ }
+ },
+ _ => noop_fold_pat(pat, self)
+ }
+ }
+ fn fold_mac(&mut self, macro: &ast::Mac) -> ast::Mac {
+ fold::fold_mac(macro, self)
+ }
+}
+
+// expand a method
+fn expand_method(m: &ast::Method, fld: &mut MacroExpander) -> SmallVector<Gc<ast::Method>> {
+ let id = fld.new_id(m.id);
+ match m.node {
+ ast::MethDecl(ident, ref generics, ref explicit_self, fn_style, decl, body, vis) => {
+ let (rewritten_fn_decl, rewritten_body)
+ = expand_and_rename_fn_decl_and_block(decl,body,fld);
+ SmallVector::one(box(GC) ast::Method {
+ attrs: m.attrs.iter().map(|a| fld.fold_attribute(*a)).collect(),
+ id: id,
+ span: fld.new_span(m.span),
+ node: ast::MethDecl(fld.fold_ident(ident),
+ fold_generics(generics, fld),
+ fld.fold_explicit_self(explicit_self),
+ fn_style,
+ rewritten_fn_decl,
+ rewritten_body,
+ vis)
+ })
+ },
+ ast::MethMac(ref mac) => {
+ let maybe_new_methods =
+ expand_mac_invoc(mac, &m.span,
+ |r|{r.make_methods()},
+ |meths,mark|{
+ meths.move_iter().map(|m|{mark_method(m,mark)})
+ .collect()},
+ fld);
+
+ let new_methods = match maybe_new_methods {
+ Some(methods) => methods,
+ None => SmallVector::zero()
+ };
+
+ // expand again if necessary
+ new_methods.move_iter().flat_map(|m| fld.fold_method(m).move_iter()).collect()
+ }
}
}
+/// Given a fn_decl and a block and a MacroExpander, expand the fn_decl, then use the
+/// PatIdents in its arguments to perform renaming in the FnDecl and
+/// the block, returning both the new FnDecl and the new Block.
+fn expand_and_rename_fn_decl_and_block(fn_decl: &ast::FnDecl, block: Gc<ast::Block>,
+ fld: &mut MacroExpander)
+ -> (Gc<ast::FnDecl>, Gc<ast::Block>) {
+ let expanded_decl = fld.fold_fn_decl(fn_decl);
+ let idents = fn_decl_arg_bindings(expanded_decl);
+ let renames =
+ idents.iter().map(|id : &ast::Ident| (*id,fresh_name(id))).collect();
+ // first, a renamer for the PatIdents, for the fn_decl:
+ let mut rename_pat_fld = PatIdentRenamer{renames: &renames};
+ let rewritten_fn_decl = rename_pat_fld.fold_fn_decl(expanded_decl);
+ // now, a renamer for *all* idents, for the body:
+ let mut rename_fld = IdentRenamer{renames: &renames};
+ let rewritten_body = fld.fold_block(rename_fld.fold_block(block));
+ (rewritten_fn_decl,rewritten_body)
+}
+
+/// A tree-folder that performs macro expansion
pub struct MacroExpander<'a, 'b> {
pub extsbox: SyntaxEnv,
pub cx: &'a mut ExtCtxt<'b>,
expand_item(item, self)
}
+ fn fold_item_underscore(&mut self, item: &ast::Item_) -> ast::Item_ {
+ expand_item_underscore(item, self)
+ }
+
fn fold_stmt(&mut self, stmt: &ast::Stmt) -> SmallVector<Gc<ast::Stmt>> {
expand_stmt(stmt, self)
}
expand_arm(arm, self)
}
+ fn fold_method(&mut self, method: Gc<ast::Method>) -> SmallVector<Gc<ast::Method>> {
+ expand_method(method, self)
+ }
+
fn new_span(&mut self, span: Span) -> Span {
new_span(self.cx, span)
}
}
+fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
+ /* this discards information in the case of macro-defining macros */
+ Span {
+ lo: sp.lo,
+ hi: sp.hi,
+ expn_info: cx.backtrace(),
+ }
+}
+
pub struct ExpansionConfig {
pub deriving_hash_type_parameter: bool,
- pub crate_id: CrateId,
+ pub crate_name: String,
}
pub struct ExportedMacros {
pub fn expand_crate(parse_sess: &parse::ParseSess,
cfg: ExpansionConfig,
+ // these are the macros being imported to this crate:
macros: Vec<ExportedMacros>,
user_exts: Vec<NamedSyntaxExtension>,
c: Crate) -> Crate {
expander.extsbox.insert(name, extension);
}
- let ret = expander.fold_crate(c);
+ let mut ret = expander.fold_crate(c);
+ ret.exported_macros = expander.cx.exported_macros.clone();
parse_sess.span_diagnostic.handler().abort_if_errors();
return ret;
}
fn fold_ident(&mut self, id: Ident) -> Ident {
ast::Ident {
name: id.name,
- ctxt: mtwt::new_mark(self.mark, id.ctxt)
+ ctxt: mtwt::apply_mark(self.mark, id.ctxt)
}
}
fn fold_mac(&mut self, m: &ast::Mac) -> ast::Mac {
MacInvocTT(ref path, ref tts, ctxt) => {
MacInvocTT(self.fold_path(path),
fold_tts(tts.as_slice(), self),
- mtwt::new_mark(self.mark, ctxt))
+ mtwt::apply_mark(self.mark, ctxt))
}
};
Spanned {
// apply a given mark to the given stmt. Used following the expansion of a macro.
fn mark_stmt(expr: &ast::Stmt, m: Mrk) -> Gc<ast::Stmt> {
Marker{mark:m}.fold_stmt(expr)
- .expect_one("marking a stmt didn't return a stmt")
+ .expect_one("marking a stmt didn't return exactly one stmt")
}
// apply a given mark to the given item. Used following the expansion of a macro.
-fn mark_item(expr: Gc<ast::Item>, m: Mrk) -> SmallVector<Gc<ast::Item>> {
+fn mark_item(expr: Gc<ast::Item>, m: Mrk) -> Gc<ast::Item> {
Marker{mark:m}.fold_item(expr)
+ .expect_one("marking an item didn't return exactly one item")
+}
+
+// apply a given mark to the given item. Used following the expansion of a macro.
+fn mark_method(expr: Gc<ast::Method>, m: Mrk) -> Gc<ast::Method> {
+ Marker{mark:m}.fold_method(expr)
+ .expect_one("marking an item didn't return exactly one method")
}
fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> {
return einfo;
}
+/// Check that there are no macro invocations left in the AST:
+pub fn check_for_macros(sess: &parse::ParseSess, krate: &ast::Crate) {
+ visit::walk_crate(&mut MacroExterminator{sess:sess}, krate, ());
+}
+
+/// A visitor that ensures that no macro invocations remain in an AST.
+struct MacroExterminator<'a>{
+ sess: &'a parse::ParseSess
+}
+
+impl<'a> visit::Visitor<()> for MacroExterminator<'a> {
+ fn visit_mac(&mut self, macro: &ast::Mac, _:()) {
+ self.sess.span_diagnostic.span_bug(macro.span,
+ "macro exterminator: expected AST \
+ with no macro invocations");
+ }
+}
+
+
#[cfg(test)]
mod test {
use super::{pattern_bindings, expand_crate, contains_macro_escape};
- use super::{NameFinderContext};
+ use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer};
use ast;
- use ast::{Attribute_, AttrOuter, MetaWord};
+ use ast::{Attribute_, AttrOuter, MetaWord, Name};
use attr;
use codemap;
use codemap::Spanned;
use ext::mtwt;
+ use fold::Folder;
use parse;
use parse::token;
use util::parser_testing::{string_to_parser};
path_finder.path_accumulator
}
+ /// A Visitor that extracts the identifiers from a thingy.
+ // as a side note, I'm starting to want to abstract over these....
+ struct IdentFinder{
+ ident_accumulator: Vec<ast::Ident>
+ }
+ impl Visitor<()> for IdentFinder {
+ fn visit_ident(&mut self, _: codemap::Span, id: ast::Ident, _: ()){
+ self.ident_accumulator.push(id);
+ }
+ }
+
+ /// Find the idents in a crate
+ fn crate_idents(the_crate: &ast::Crate) -> Vec<ast::Ident> {
+ let mut ident_finder = IdentFinder{ident_accumulator: Vec::new()};
+ visit::walk_crate(&mut ident_finder, the_crate, ());
+ ident_finder.ident_accumulator
+ }
// these following tests are quite fragile, in that they don't test what
// *kind* of failure occurs.
// should fail:
let cfg = ::syntax::ext::expand::ExpansionConfig {
deriving_hash_type_parameter: false,
- crate_id: from_str("test").unwrap(),
+ crate_name: "test".to_string(),
};
expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
}
Vec::new(), &sess);
let cfg = ::syntax::ext::expand::ExpansionConfig {
deriving_hash_type_parameter: false,
- crate_id: from_str("test").unwrap(),
+ crate_name: "test".to_string(),
};
expand_crate(&sess,cfg,vec!(),vec!(),crate_ast);
}
Vec::new(), &sess);
let cfg = ::syntax::ext::expand::ExpansionConfig {
deriving_hash_type_parameter: false,
- crate_id: from_str("test").unwrap(),
+ crate_name: "test".to_string(),
};
expand_crate(&sess, cfg, vec!(), vec!(), crate_ast);
}
// the cfg argument actually does matter, here...
let cfg = ::syntax::ext::expand::ExpansionConfig {
deriving_hash_type_parameter: false,
- crate_id: from_str("test").unwrap(),
+ crate_name: "test".to_string(),
};
expand_crate(&ps,cfg,vec!(),vec!(),crate_ast)
}
// find the pat_ident paths in a crate
fn crate_bindings(the_crate : &ast::Crate) -> Vec<ast::Ident> {
- let mut name_finder = NameFinderContext{ident_accumulator:Vec::new()};
+ let mut name_finder = PatIdentFinder{ident_accumulator:Vec::new()};
visit::walk_crate(&mut name_finder, the_crate, ());
name_finder.ident_accumulator
}
-
//fn expand_and_resolve(crate_str: @str) -> ast::crate {
//let expanded_ast = expand_crate_str(crate_str);
// println!("expanded: {:?}\n",expanded_ast);
//}
//fn expand_and_resolve_and_pretty_print (crate_str: @str) -> String {
//let resolved_ast = expand_and_resolve(crate_str);
- //pprust::to_str(&resolved_ast,fake_print_crate,get_ident_interner())
+ //pprust::to_string(&resolved_ast,fake_print_crate,get_ident_interner())
//}
#[test] fn macro_tokens_should_match(){
"macro_rules! m((a)=>(13)) fn main(){m!(a);}".to_string());
}
+ // should be able to use a bound identifier as a literal in a macro definition:
+ #[test] fn self_macro_parsing(){
+ expand_crate_str(
+ "macro_rules! foo ((zz) => (287u;))
+ fn f(zz : int) {foo!(zz);}".to_string()
+ );
+ }
+
// renaming tests expand a crate and then check that the bindings match
// the right varrefs. The specification of the test case includes the
// text of the crate, and also an array of arrays. Each element in the
// but *shouldn't* bind because it was inserted by a different macro....
// can't write this test case until we have macro-generating macros.
- // FIXME #9383 : lambda var hygiene
- // interesting... can't even write this test, yet, because the name-finder
- // only finds pattern vars. Time to upgrade test framework.
- /*#[test]
- fn issue_9383(){
+ // method arg hygiene
+ // method expands to fn get_x(&self_0, x_1:int) {self_0 + self_2 + x_3 + x_1}
+ #[test] fn method_arg_hygiene(){
run_renaming_test(
- &("macro_rules! bad_macro (($ex:expr) => ({(|_x| { $ex }) (9) }))
- fn takes_x(_x : int) { assert_eq!(bad_macro!(_x),8); }
- fn main() { takes_x(8); }",
- vec!(vec!()),false),
+ &("macro_rules! inject_x (()=>(x))
+ macro_rules! inject_self (()=>(self))
+ struct A;
+ impl A{fn get_x(&self, x: int) {self + inject_self!() + inject_x!() + x;} }",
+ vec!(vec!(0),vec!(3)),
+ true),
0)
- }*/
+ }
+
+ // ooh, got another bite?
+ // expands to struct A; impl A {fn thingy(&self_1) {self_1;}}
+ #[test] fn method_arg_hygiene_2(){
+ run_renaming_test(
+ &("struct A;
+ macro_rules! add_method (($T:ty) =>
+ (impl $T { fn thingy(&self) {self;} }))
+ add_method!(A)",
+ vec!(vec!(0)),
+ true),
+ 0)
+ }
+
+ // item fn hygiene
+ // expands to fn q(x_1:int){fn g(x_2:int){x_2 + x_1};}
+ #[test] fn issue_9383(){
+ run_renaming_test(
+ &("macro_rules! bad_macro (($ex:expr) => (fn g(x:int){ x + $ex }))
+ fn q(x:int) { bad_macro!(x); }",
+ vec!(vec!(1),vec!(0)),true),
+ 0)
+ }
+
+ // closure arg hygiene (ExprFnBlock)
+ // expands to fn f(){(|x_1 : int| {(x_2 + x_1)})(3);}
+ #[test] fn closure_arg_hygiene(){
+ run_renaming_test(
+ &("macro_rules! inject_x (()=>(x))
+ fn f(){(|x : int| {(inject_x!() + x)})(3);}",
+ vec!(vec!(1)),
+ true),
+ 0)
+ }
+
+ // closure arg hygiene (ExprProc)
+ // expands to fn f(){(proc(x_1 : int) {(x_2 + x_1)})(3);}
+ #[test] fn closure_arg_hygiene_2(){
+ run_renaming_test(
+ &("macro_rules! inject_x (()=>(x))
+ fn f(){ (proc(x : int){(inject_x!() + x)})(3); }",
+ vec!(vec!(1)),
+ true),
+ 0)
+ }
+
+ // macro_rules in method position. Sadly, unimplemented.
+ #[test] fn macro_in_method_posn(){
+ expand_crate_str(
+ "macro_rules! my_method (() => (fn thirteen(&self) -> int {13}))
+ struct A;
+ impl A{ my_method!()}
+ fn f(){A.thirteen;}".to_string());
+ }
+
+ // another nested macro
+ // expands to impl Entries {fn size_hint(&self_1) {self_1;}
+ #[test] fn item_macro_workaround(){
+ run_renaming_test(
+ &("macro_rules! item { ($i:item) => {$i}}
+ struct Entries;
+ macro_rules! iterator_impl {
+ () => { item!( impl Entries { fn size_hint(&self) { self;}})}}
+ iterator_impl! { }",
+ vec!(vec!(0)), true),
+ 0)
+ }
// run one of the renaming tests
fn run_renaming_test(t: &RenamingTest, test_idx: uint) {
assert!((shouldmatch.len() == 0) ||
(varrefs.len() > *shouldmatch.iter().max().unwrap()));
for (idx,varref) in varrefs.iter().enumerate() {
+ let print_hygiene_debug_info = || {
+ // good lord, you can't make a path with 0 segments, can you?
+ let final_varref_ident = match varref.segments.last() {
+ Some(pathsegment) => pathsegment.identifier,
+ None => fail!("varref with 0 path segments?")
+ };
+ let varref_name = mtwt::resolve(final_varref_ident);
+ let varref_idents : Vec<ast::Ident>
+ = varref.segments.iter().map(|s| s.identifier)
+ .collect();
+ println!("varref #{}: {}, resolves to {}",idx, varref_idents, varref_name);
+ let string = token::get_ident(final_varref_ident);
+ println!("varref's first segment's string: \"{}\"", string.get());
+ println!("binding #{}: {}, resolves to {}",
+ binding_idx, *bindings.get(binding_idx), binding_name);
+ mtwt::with_sctable(|x| mtwt::display_sctable(x));
+ };
if shouldmatch.contains(&idx) {
// it should be a path of length 1, and it should
// be free-identifier=? or bound-identifier=? to the given binding
assert_eq!(varref.segments.len(),1);
- let varref_name = mtwt::resolve(varref.segments
- .get(0)
- .identifier);
+ let varref_name = mtwt::resolve(varref.segments.get(0).identifier);
let varref_marks = mtwt::marksof(varref.segments
.get(0)
.identifier
.ctxt,
invalid_name);
if !(varref_name==binding_name) {
- let varref_idents : Vec<ast::Ident>
- = varref.segments.iter().map(|s|
- s.identifier)
- .collect();
println!("uh oh, should match but doesn't:");
- println!("varref #{}: {}",idx, varref_idents);
- println!("binding #{}: {}", binding_idx, *bindings.get(binding_idx));
- mtwt::with_sctable(|x| mtwt::display_sctable(x));
+ print_hygiene_debug_info();
}
assert_eq!(varref_name,binding_name);
if bound_ident_check {
assert_eq!(varref_marks,binding_marks.clone());
}
} else {
+ let varref_name = mtwt::resolve(varref.segments.get(0).identifier);
let fail = (varref.segments.len() == 1)
- && (mtwt::resolve(varref.segments.get(0).identifier)
- == binding_name);
+ && (varref_name == binding_name);
// temp debugging:
if fail {
- let varref_idents : Vec<ast::Ident>
- = varref.segments.iter().map(|s|
- s.identifier)
- .collect();
println!("failure on test {}",test_idx);
println!("text of test case: \"{}\"", teststr);
println!("");
println!("uh oh, matches but shouldn't:");
- println!("varref: {}",varref_idents);
- // good lord, you can't make a path with 0 segments, can you?
- let string = token::get_ident(varref.segments
- .get(0)
- .identifier);
- println!("varref's first segment's uint: {}, and string: \"{}\"",
- varref.segments.get(0).identifier.name,
- string.get());
- println!("binding: {}", *bindings.get(binding_idx));
- mtwt::with_sctable(|x| mtwt::display_sctable(x));
+ print_hygiene_debug_info();
}
assert!(!fail);
}
}
#[test] fn fmt_in_macro_used_inside_module_macro() {
- let crate_str = "macro_rules! fmt_wrap(($b:expr)=>($b.to_str()))
+ let crate_str = "macro_rules! fmt_wrap(($b:expr)=>($b.to_string()))
macro_rules! foo_module (() => (mod generated { fn a() { let xx = 147; fmt_wrap!(xx);}}))
foo_module!()
".to_string();
// 'None' is listed as an identifier pattern because we don't yet know that
// it's the name of a 0-ary variant, and that 'i' appears twice in succession.
#[test]
- fn crate_idents(){
+ fn crate_bindings_test(){
let the_crate = string_to_crate("fn main (a : int) -> int {|b| {
match 34 {None => 3, Some(i) | i => j, Foo{k:z,l:y} => \"banana\"}} }".to_string());
let idents = crate_bindings(&the_crate);
assert_eq!(idents, strs_to_idents(vec!("a","b","None","i","i","z","y")));
}
- //
+ // test the IdentRenamer directly
+ #[test]
+ fn ident_renamer_test () {
+ let the_crate = string_to_crate("fn f(x : int){let x = x; x}".to_string());
+ let f_ident = token::str_to_ident("f");
+ let x_ident = token::str_to_ident("x");
+ let int_ident = token::str_to_ident("int");
+ let renames = vec!((x_ident,Name(16)));
+ let mut renamer = IdentRenamer{renames: &renames};
+ let renamed_crate = renamer.fold_crate(the_crate);
+ let idents = crate_idents(&renamed_crate);
+ let resolved : Vec<ast::Name> = idents.iter().map(|id| mtwt::resolve(*id)).collect();
+ assert_eq!(resolved,vec!(f_ident.name,Name(16),int_ident.name,Name(16),Name(16),Name(16)));
+ }
+
+ // test the PatIdentRenamer; only PatIdents get renamed
+ #[test]
+ fn pat_ident_renamer_test () {
+ let the_crate = string_to_crate("fn f(x : int){let x = x; x}".to_string());
+ let f_ident = token::str_to_ident("f");
+ let x_ident = token::str_to_ident("x");
+ let int_ident = token::str_to_ident("int");
+ let renames = vec!((x_ident,Name(16)));
+ let mut renamer = PatIdentRenamer{renames: &renames};
+ let renamed_crate = renamer.fold_crate(the_crate);
+ let idents = crate_idents(&renamed_crate);
+ let resolved : Vec<ast::Name> = idents.iter().map(|id| mtwt::resolve(*id)).collect();
+ let x_name = x_ident.name;
+ assert_eq!(resolved,vec!(f_ident.name,Name(16),int_ident.name,Name(16),x_name,x_name));
+ }
+
}
ecx: &'a mut ExtCtxt<'b>,
fmtsp: Span,
- // Parsed argument expressions and the types that we've found so far for
- // them.
+ /// Parsed argument expressions and the types that we've found so far for
+ /// them.
args: Vec<Gc<ast::Expr>>,
arg_types: Vec<Option<ArgumentType>>,
- // Parsed named expressions and the types that we've found for them so far.
- // Note that we keep a side-array of the ordering of the named arguments
- // found to be sure that we can translate them in the same order that they
- // were declared in.
+ /// Parsed named expressions and the types that we've found for them so far.
+ /// Note that we keep a side-array of the ordering of the named arguments
+ /// found to be sure that we can translate them in the same order that they
+ /// were declared in.
names: HashMap<String, Gc<ast::Expr>>,
name_types: HashMap<String, ArgumentType>,
name_ordering: Vec<String>,
- // Collection of the compiled `rt::Piece` structures
+ /// Collection of the compiled `rt::Piece` structures
pieces: Vec<Gc<ast::Expr>>,
name_positions: HashMap<String, uint>,
method_statics: Vec<Gc<ast::Item>>,
- // Updated as arguments are consumed or methods are entered
+ /// Updated as arguments are consumed or methods are entered
nest_level: uint,
next_arg: uint,
}
_ => {
ecx.span_err(p.span,
format!("expected ident for named argument, but found `{}`",
- p.this_token_to_str()).as_slice());
+ p.this_token_to_string()).as_slice());
return (invocation, None);
}
};
fmtsp: sp,
};
cx.fmtsp = efmt.span;
- let fmt = match expr_to_str(cx.ecx,
+ let fmt = match expr_to_string(cx.ecx,
efmt,
"format argument must be a string literal.") {
Some((fmt, _)) => fmt,
-> Box<base::MacResult> {
cx.print_backtrace();
- println!("{}", print::pprust::tt_to_str(&ast::TTDelim(
+ println!("{}", print::pprust::tt_to_string(&ast::TTDelim(
Rc::new(tt.iter().map(|x| (*x).clone()).collect()))));
// any so that `log_syntax` can be invoked as an expression and item.
use std::rc::Rc;
use std::collections::HashMap;
-// the SCTable contains a table of SyntaxContext_'s. It
-// represents a flattened tree structure, to avoid having
-// managed pointers everywhere (that caused an ICE).
-// the mark_memo and rename_memo fields are side-tables
-// that ensure that adding the same mark to the same context
-// gives you back the same context as before. This shouldn't
-// change the semantics--everything here is immutable--but
-// it should cut down on memory use *a lot*; applying a mark
-// to a tree containing 50 identifiers would otherwise generate
-// 50 new contexts
+/// The SCTable contains a table of SyntaxContext_'s. It
+/// represents a flattened tree structure, to avoid having
+/// managed pointers everywhere (that caused an ICE).
+/// the mark_memo and rename_memo fields are side-tables
+/// that ensure that adding the same mark to the same context
+/// gives you back the same context as before. This shouldn't
+/// change the semantics--everything here is immutable--but
+/// it should cut down on memory use *a lot*; applying a mark
+/// to a tree containing 50 identifiers would otherwise generate
+/// 50 new contexts
pub struct SCTable {
table: RefCell<Vec<SyntaxContext_>>,
mark_memo: RefCell<HashMap<(SyntaxContext,Mrk),SyntaxContext>>,
pub enum SyntaxContext_ {
EmptyCtxt,
Mark (Mrk,SyntaxContext),
- // flattening the name and syntaxcontext into the rename...
- // HIDDEN INVARIANTS:
- // 1) the first name in a Rename node
- // can only be a programmer-supplied name.
- // 2) Every Rename node with a given Name in the
- // "to" slot must have the same name and context
- // in the "from" slot. In essence, they're all
- // pointers to a single "rename" event node.
+ /// flattening the name and syntaxcontext into the rename...
+ /// HIDDEN INVARIANTS:
+ /// 1) the first name in a Rename node
+ /// can only be a programmer-supplied name.
+ /// 2) Every Rename node with a given Name in the
+ /// "to" slot must have the same name and context
+ /// in the "from" slot. In essence, they're all
+ /// pointers to a single "rename" event node.
Rename (Ident,Name,SyntaxContext),
- // actually, IllegalCtxt may not be necessary.
+ /// actually, IllegalCtxt may not be necessary.
IllegalCtxt
}
+/// A list of ident->name renamings
+pub type RenameList = Vec<(Ident, Name)>;
+
/// Extend a syntax context with a given mark
-pub fn new_mark(m: Mrk, tail: SyntaxContext) -> SyntaxContext {
- with_sctable(|table| new_mark_internal(m, tail, table))
+pub fn apply_mark(m: Mrk, ctxt: SyntaxContext) -> SyntaxContext {
+ with_sctable(|table| apply_mark_internal(m, ctxt, table))
}
-// Extend a syntax context with a given mark and table
-fn new_mark_internal(m: Mrk, tail: SyntaxContext, table: &SCTable) -> SyntaxContext {
- let key = (tail, m);
+/// Extend a syntax context with a given mark and sctable (explicit memoization)
+fn apply_mark_internal(m: Mrk, ctxt: SyntaxContext, table: &SCTable) -> SyntaxContext {
+ let key = (ctxt, m);
let new_ctxt = |_: &(SyntaxContext, Mrk)|
- idx_push(&mut *table.table.borrow_mut(), Mark(m, tail));
+ idx_push(&mut *table.table.borrow_mut(), Mark(m, ctxt));
*table.mark_memo.borrow_mut().find_or_insert_with(key, new_ctxt)
}
/// Extend a syntax context with a given rename
-pub fn new_rename(id: Ident, to:Name,
- tail: SyntaxContext) -> SyntaxContext {
- with_sctable(|table| new_rename_internal(id, to, tail, table))
+pub fn apply_rename(id: Ident, to:Name,
+ ctxt: SyntaxContext) -> SyntaxContext {
+ with_sctable(|table| apply_rename_internal(id, to, ctxt, table))
}
-// Extend a syntax context with a given rename and sctable
-fn new_rename_internal(id: Ident,
+/// Extend a syntax context with a given rename and sctable (explicit memoization)
+fn apply_rename_internal(id: Ident,
to: Name,
- tail: SyntaxContext,
+ ctxt: SyntaxContext,
table: &SCTable) -> SyntaxContext {
- let key = (tail,id,to);
- let new_ctxt = |_: &(SyntaxContext, Ident, Mrk)|
- idx_push(&mut *table.table.borrow_mut(), Rename(id, to, tail));
+ let key = (ctxt, id, to);
+ let new_ctxt = |_: &(SyntaxContext, Ident, Name)|
+ idx_push(&mut *table.table.borrow_mut(), Rename(id, to, ctxt));
*table.rename_memo.borrow_mut().find_or_insert_with(key, new_ctxt)
}
+/// Apply a list of renamings to a context
+// if these rename lists get long, it would make sense
+// to consider memoizing this fold. This may come up
+// when we add hygiene to item names.
+pub fn apply_renames(renames: &RenameList, ctxt: SyntaxContext) -> SyntaxContext {
+ renames.iter().fold(ctxt, |ctxt, &(from, to)| {
+ apply_rename(from, to, ctxt)
+ })
+}
+
/// Fetch the SCTable from TLS, create one if it doesn't yet exist.
pub fn with_sctable<T>(op: |&SCTable| -> T) -> T {
local_data_key!(sctable_key: Rc<SCTable>)
with_resolve_table_mut(|table| *table = HashMap::new());
}
-// Add a value to the end of a vec, return its index
-fn idx_push<T>(vec: &mut Vec<T> , val: T) -> u32 {
+/// Add a value to the end of a vec, return its index
+fn idx_push<T>(vec: &mut Vec<T>, val: T) -> u32 {
vec.push(val);
(vec.len() - 1) as u32
}
}
}
-// Resolve a syntax object to a name, per MTWT.
-// adding memoization to resolve 500+ seconds in resolve for librustc (!)
+/// Resolve a syntax object to a name, per MTWT.
+/// adding memoization to resolve 500+ seconds in resolve for librustc (!)
fn resolve_internal(id: Ident,
table: &SCTable,
resolve_table: &mut ResolveTable) -> Name {
})
}
-// Push a name... unless it matches the one on top, in which
-// case pop and discard (so two of the same marks cancel)
+/// Push a name... unless it matches the one on top, in which
+/// case pop and discard (so two of the same marks cancel)
fn xor_push(marks: &mut Vec<Mrk>, mark: Mrk) {
if (marks.len() > 0) && (*marks.last().unwrap() == mark) {
marks.pop().unwrap();
#[cfg(test)]
mod tests {
- use ast::*;
- use super::{resolve, xor_push, new_mark_internal, new_sctable_internal};
- use super::{new_rename_internal, marksof_internal, resolve_internal};
+ use ast::{EMPTY_CTXT, Ident, Mrk, Name, SyntaxContext};
+ use super::{resolve, xor_push, apply_mark_internal, new_sctable_internal};
+ use super::{apply_rename_internal, apply_renames, marksof_internal, resolve_internal};
use super::{SCTable, EmptyCtxt, Mark, Rename, IllegalCtxt};
use std::collections::HashMap;
assert_eq!(s.clone(), vec!(14));
}
- fn id(n: Name, s: SyntaxContext) -> Ident {
- Ident {name: n, ctxt: s}
+ fn id(n: u32, s: SyntaxContext) -> Ident {
+ Ident {name: Name(n), ctxt: s}
}
// because of the SCTable, I now need a tidy way of
-> SyntaxContext {
tscs.iter().rev().fold(tail, |tail : SyntaxContext, tsc : &TestSC|
{match *tsc {
- M(mrk) => new_mark_internal(mrk,tail,table),
- R(ident,name) => new_rename_internal(ident,name,tail,table)}})
+ M(mrk) => apply_mark_internal(mrk,tail,table),
+ R(ident,name) => apply_rename_internal(ident,name,tail,table)}})
}
// gather a SyntaxContext back into a vector of TestSCs
fn test_unfold_refold(){
let mut t = new_sctable_internal();
- let test_sc = vec!(M(3),R(id(101,0),14),M(9));
+ let test_sc = vec!(M(3),R(id(101,0),Name(14)),M(9));
assert_eq!(unfold_test_sc(test_sc.clone(),EMPTY_CTXT,&mut t),4);
{
let table = t.table.borrow();
assert!(*table.get(2) == Mark(9,0));
- assert!(*table.get(3) == Rename(id(101,0),14,2));
+ assert!(*table.get(3) == Rename(id(101,0),Name(14),2));
assert!(*table.get(4) == Mark(3,3));
}
assert_eq!(refold_test_sc(4,&t),test_sc);
fn unfold_marks(mrks: Vec<Mrk> , tail: SyntaxContext, table: &SCTable)
-> SyntaxContext {
mrks.iter().rev().fold(tail, |tail:SyntaxContext, mrk:&Mrk|
- {new_mark_internal(*mrk,tail,table)})
+ {apply_mark_internal(*mrk,tail,table)})
}
#[test] fn unfold_marks_test() {
#[test]
fn test_marksof () {
- let stopname = 242;
- let name1 = 243;
+ let stopname = Name(242);
+ let name1 = Name(243);
let mut t = new_sctable_internal();
assert_eq!(marksof_internal (EMPTY_CTXT,stopname,&t),Vec::new());
// FIXME #5074: ANF'd to dodge nested calls
assert_eq! (marksof_internal (ans, stopname,&t), vec!(16));}
// rename where stop doesn't match:
{ let chain = vec!(M(9),
- R(id(name1,
- new_mark_internal (4, EMPTY_CTXT,&mut t)),
- 100101102),
+ R(id(name1.uint() as u32,
+ apply_mark_internal (4, EMPTY_CTXT,&mut t)),
+ Name(100101102)),
M(14));
let ans = unfold_test_sc(chain,EMPTY_CTXT,&mut t);
assert_eq! (marksof_internal (ans, stopname, &t), vec!(9,14));}
// rename where stop does match
- { let name1sc = new_mark_internal(4, EMPTY_CTXT, &mut t);
+ { let name1sc = apply_mark_internal(4, EMPTY_CTXT, &mut t);
let chain = vec!(M(9),
- R(id(name1, name1sc),
+ R(id(name1.uint() as u32, name1sc),
stopname),
M(14));
let ans = unfold_test_sc(chain,EMPTY_CTXT,&mut t);
let mut t = new_sctable_internal();
let mut rt = HashMap::new();
// - ctxt is MT
- assert_eq!(resolve_internal(id(a,EMPTY_CTXT),&mut t, &mut rt),a);
+ assert_eq!(resolve_internal(id(a,EMPTY_CTXT),&mut t, &mut rt),Name(a));
// - simple ignored marks
{ let sc = unfold_marks(vec!(1,2,3),EMPTY_CTXT,&mut t);
- assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt),a);}
+ assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt),Name(a));}
// - orthogonal rename where names don't match
- { let sc = unfold_test_sc(vec!(R(id(50,EMPTY_CTXT),51),M(12)),EMPTY_CTXT,&mut t);
- assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt),a);}
+ { let sc = unfold_test_sc(vec!(R(id(50,EMPTY_CTXT),Name(51)),M(12)),EMPTY_CTXT,&mut t);
+ assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt),Name(a));}
// - rename where names do match, but marks don't
- { let sc1 = new_mark_internal(1,EMPTY_CTXT,&mut t);
- let sc = unfold_test_sc(vec!(R(id(a,sc1),50),
+ { let sc1 = apply_mark_internal(1,EMPTY_CTXT,&mut t);
+ let sc = unfold_test_sc(vec!(R(id(a,sc1),Name(50)),
M(1),
M(2)),
EMPTY_CTXT,&mut t);
- assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), a);}
+ assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), Name(a));}
// - rename where names and marks match
{ let sc1 = unfold_test_sc(vec!(M(1),M(2)),EMPTY_CTXT,&mut t);
- let sc = unfold_test_sc(vec!(R(id(a,sc1),50),M(1),M(2)),EMPTY_CTXT,&mut t);
- assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), 50); }
+ let sc = unfold_test_sc(vec!(R(id(a,sc1),Name(50)),M(1),M(2)),EMPTY_CTXT,&mut t);
+ assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), Name(50)); }
// - rename where names and marks match by literal sharing
{ let sc1 = unfold_test_sc(vec!(M(1),M(2)),EMPTY_CTXT,&mut t);
- let sc = unfold_test_sc(vec!(R(id(a,sc1),50)),sc1,&mut t);
- assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), 50); }
+ let sc = unfold_test_sc(vec!(R(id(a,sc1),Name(50))),sc1,&mut t);
+ assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), Name(50)); }
// - two renames of the same var.. can only happen if you use
// local-expand to prevent the inner binding from being renamed
// during the rename-pass caused by the first:
println!("about to run bad test");
- { let sc = unfold_test_sc(vec!(R(id(a,EMPTY_CTXT),50),
- R(id(a,EMPTY_CTXT),51)),
+ { let sc = unfold_test_sc(vec!(R(id(a,EMPTY_CTXT),Name(50)),
+ R(id(a,EMPTY_CTXT),Name(51))),
EMPTY_CTXT,&mut t);
- assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), 51); }
+ assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt), Name(51)); }
// the simplest double-rename:
- { let a_to_a50 = new_rename_internal(id(a,EMPTY_CTXT),50,EMPTY_CTXT,&mut t);
- let a50_to_a51 = new_rename_internal(id(a,a_to_a50),51,a_to_a50,&mut t);
- assert_eq!(resolve_internal(id(a,a50_to_a51),&mut t, &mut rt),51);
+ { let a_to_a50 = apply_rename_internal(id(a,EMPTY_CTXT),Name(50),EMPTY_CTXT,&mut t);
+ let a50_to_a51 = apply_rename_internal(id(a,a_to_a50),Name(51),a_to_a50,&mut t);
+ assert_eq!(resolve_internal(id(a,a50_to_a51),&mut t, &mut rt),Name(51));
// mark on the outside doesn't stop rename:
- let sc = new_mark_internal(9,a50_to_a51,&mut t);
- assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt),51);
+ let sc = apply_mark_internal(9,a50_to_a51,&mut t);
+ assert_eq!(resolve_internal(id(a,sc),&mut t, &mut rt),Name(51));
// but mark on the inside does:
- let a50_to_a51_b = unfold_test_sc(vec!(R(id(a,a_to_a50),51),
+ let a50_to_a51_b = unfold_test_sc(vec!(R(id(a,a_to_a50),Name(51)),
M(9)),
a_to_a50,
&mut t);
- assert_eq!(resolve_internal(id(a,a50_to_a51_b),&mut t, &mut rt),50);}
+ assert_eq!(resolve_internal(id(a,a50_to_a51_b),&mut t, &mut rt),Name(50));}
}
#[test]
fn mtwt_resolve_test(){
let a = 40;
- assert_eq!(resolve(id(a,EMPTY_CTXT)),a);
+ assert_eq!(resolve(id(a,EMPTY_CTXT)),Name(a));
}
#[test]
fn hashing_tests () {
let mut t = new_sctable_internal();
- assert_eq!(new_mark_internal(12,EMPTY_CTXT,&mut t),2);
- assert_eq!(new_mark_internal(13,EMPTY_CTXT,&mut t),3);
+ assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),2);
+ assert_eq!(apply_mark_internal(13,EMPTY_CTXT,&mut t),3);
// using the same one again should result in the same index:
- assert_eq!(new_mark_internal(12,EMPTY_CTXT,&mut t),2);
+ assert_eq!(apply_mark_internal(12,EMPTY_CTXT,&mut t),2);
// I'm assuming that the rename table will behave the same....
}
resolve_internal(id(30,EMPTY_CTXT),&mut t, &mut rt);
assert_eq!(rt.len(),2);
}
+
+ #[test]
+ fn new_resolves_test() {
+ let renames = vec!((Ident{name:Name(23),ctxt:EMPTY_CTXT},Name(24)),
+ (Ident{name:Name(29),ctxt:EMPTY_CTXT},Name(29)));
+ let new_ctxt1 = apply_renames(&renames,EMPTY_CTXT);
+ assert_eq!(resolve(Ident{name:Name(23),ctxt:new_ctxt1}),Name(24));
+ assert_eq!(resolve(Ident{name:Name(29),ctxt:new_ctxt1}),Name(29));
+ }
}
}
}
- impl_to_source!(ast::Ty, ty_to_str)
- impl_to_source!(ast::Block, block_to_str)
- impl_to_source!(ast::Arg, arg_to_str)
- impl_to_source!(Generics, generics_to_str)
- impl_to_source!(Gc<ast::Item>, item_to_str)
- impl_to_source!(Gc<ast::Expr>, expr_to_str)
- impl_to_source!(Gc<ast::Pat>, pat_to_str)
+ impl_to_source!(ast::Ty, ty_to_string)
+ impl_to_source!(ast::Block, block_to_string)
+ impl_to_source!(ast::Arg, arg_to_string)
+ impl_to_source!(Generics, generics_to_string)
+ impl_to_source!(Gc<ast::Item>, item_to_string)
+ impl_to_source!(Gc<ast::Expr>, expr_to_string)
+ impl_to_source!(Gc<ast::Pat>, pat_to_string)
impl_to_source_slice!(ast::Ty, ", ")
impl_to_source_slice!(Gc<ast::Item>, "\n\n")
fn to_source(&self) -> String {
let lit = dummy_spanned(ast::LitStr(
token::intern_and_get_ident(*self), ast::CookedStr));
- pprust::lit_to_str(&lit)
+ pprust::lit_to_string(&lit)
}
}
impl ToSource for bool {
fn to_source(&self) -> String {
let lit = dummy_spanned(ast::LitBool(*self));
- pprust::lit_to_str(&lit)
+ pprust::lit_to_string(&lit)
}
}
impl ToSource for char {
fn to_source(&self) -> String {
let lit = dummy_spanned(ast::LitChar(*self));
- pprust::lit_to_str(&lit)
+ pprust::lit_to_string(&lit)
}
}
impl ToSource for $t {
fn to_source(&self) -> String {
let lit = dummy_spanned(ast::LitInt(*self as i64, ast::$tag));
- pprust::lit_to_str(&lit)
+ pprust::lit_to_string(&lit)
}
}
);
impl ToSource for $t {
fn to_source(&self) -> String {
let lit = dummy_spanned(ast::LitUint(*self as u64, ast::$tag));
- pprust::lit_to_str(&lit)
+ pprust::lit_to_string(&lit)
}
}
);
vec!(e_str))
}
+// Lift a name to the expr that evaluates to that name
+fn mk_name(cx: &ExtCtxt, sp: Span, ident: ast::Ident) -> Gc<ast::Expr> {
+ let e_str = cx.expr_str(sp, token::get_ident(ident));
+ cx.expr_method_call(sp,
+ cx.expr_ident(sp, id_ext("ext_cx")),
+ id_ext("name_of"),
+ vec!(e_str))
+}
+
fn mk_ast_path(cx: &ExtCtxt, sp: Span, name: &str) -> Gc<ast::Expr> {
let idents = vec!(id_ext("syntax"), id_ext("ast"), id_ext(name));
cx.expr_path(cx.path_global(sp, idents))
}
LIT_BYTE(i) => {
- let e_byte = cx.expr_lit(sp, ast::LitByte(i));
+ let e_byte = mk_name(cx, sp, i.ident());
return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_BYTE"), vec!(e_byte));
}
LIT_CHAR(i) => {
- let e_char = cx.expr_lit(sp, ast::LitChar(i));
+ let e_char = mk_name(cx, sp, i.ident());
return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_CHAR"), vec!(e_char));
}
- LIT_INT(i, ity) => {
- let s_ity = match ity {
- ast::TyI => "TyI",
- ast::TyI8 => "TyI8",
- ast::TyI16 => "TyI16",
- ast::TyI32 => "TyI32",
- ast::TyI64 => "TyI64"
- };
- let e_ity = mk_ast_path(cx, sp, s_ity);
- let e_i64 = cx.expr_lit(sp, ast::LitInt(i, ast::TyI64));
- return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_INT"), vec!(e_i64, e_ity));
+ LIT_INTEGER(i) => {
+ let e_int = mk_name(cx, sp, i.ident());
+ return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_INTEGER"), vec!(e_int));
}
- LIT_UINT(u, uty) => {
- let s_uty = match uty {
- ast::TyU => "TyU",
- ast::TyU8 => "TyU8",
- ast::TyU16 => "TyU16",
- ast::TyU32 => "TyU32",
- ast::TyU64 => "TyU64"
- };
- let e_uty = mk_ast_path(cx, sp, s_uty);
- let e_u64 = cx.expr_lit(sp, ast::LitUint(u, ast::TyU64));
- return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_UINT"), vec!(e_u64, e_uty));
- }
-
- LIT_INT_UNSUFFIXED(i) => {
- let e_i64 = cx.expr_lit(sp, ast::LitInt(i, ast::TyI64));
- return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_INT_UNSUFFIXED"), vec!(e_i64));
- }
-
- LIT_FLOAT(fident, fty) => {
- let s_fty = match fty {
- ast::TyF32 => "TyF32",
- ast::TyF64 => "TyF64",
- };
- let e_fty = mk_ast_path(cx, sp, s_fty);
- let e_fident = mk_ident(cx, sp, fident);
- return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_FLOAT"), vec!(e_fident, e_fty));
+ LIT_FLOAT(fident) => {
+ let e_fident = mk_name(cx, sp, fident.ident());
+ return cx.expr_call(sp, mk_token_path(cx, sp, "LIT_FLOAT"), vec!(e_fident));
}
LIT_STR(ident) => {
return cx.expr_call(sp,
mk_token_path(cx, sp, "LIT_STR"),
- vec!(mk_ident(cx, sp, ident)));
+ vec!(mk_name(cx, sp, ident.ident())));
}
LIT_STR_RAW(ident, n) => {
return cx.expr_call(sp,
mk_token_path(cx, sp, "LIT_STR_RAW"),
- vec!(mk_ident(cx, sp, ident), cx.expr_uint(sp, n)));
+ vec!(mk_name(cx, sp, ident.ident()), cx.expr_uint(sp, n)));
}
IDENT(ident, b) => {
DOC_COMMENT(ident) => {
return cx.expr_call(sp,
mk_token_path(cx, sp, "DOC_COMMENT"),
- vec!(mk_ident(cx, sp, ident)));
+ vec!(mk_name(cx, sp, ident.ident())));
}
INTERPOLATED(_) => fail!("quote! with interpolated token"),
// the column/row/filename of the expression, or they include
// a given file into the current one.
-/* line!(): expands to the current line number */
+/// line!(): expands to the current line number
pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Box<base::MacResult> {
base::check_zero_tts(cx, sp, tts, "line!");
base::MacExpr::new(cx.expr_uint(topmost.call_site, loc.col.to_uint()))
}
-/* file!(): expands to the current filename */
-/* The filemap (`loc.file`) contains a bunch more information we could spit
- * out if we wanted. */
+/// file!(): expands to the current filename */
+/// The filemap (`loc.file`) contains a bunch more information we could spit
+/// out if we wanted.
pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Box<base::MacResult> {
base::check_zero_tts(cx, sp, tts, "file!");
pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Box<base::MacResult> {
- let s = pprust::tts_to_str(tts);
+ let s = pprust::tts_to_string(tts);
base::MacExpr::new(cx.expr_str(sp,
token::intern_and_get_ident(s.as_slice())))
}
token::intern_and_get_ident(string.as_slice())))
}
-// include! : parse the given file as an expr
-// This is generally a bad idea because it's going to behave
-// unhygienically.
+/// include! : parse the given file as an expr
+/// This is generally a bad idea because it's going to behave
+/// unhygienically.
pub fn expand_include(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Box<base::MacResult> {
let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
Some(src) => {
// Add this input file to the code map to make it available as
// dependency information
- let filename = file.display().to_str();
+ let filename = file.display().to_string();
let interned = token::intern_and_get_ident(src);
cx.codemap().new_filemap(filename, src.to_string());
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// Earley-like parser for macros.
+//! This is an Earley-like parser, without support for in-grammar nonterminals,
+//! only by calling out to the main rust parser for named nonterminals (which it
+//! commits to fully when it hits one in a grammar). This means that there are no
+//! completer or predictor rules, and therefore no need to store one column per
+//! token: instead, there's a set of current Earley items and a set of next
+//! ones. Instead of NTs, we have a special case for Kleene star. The big-O, in
+//! pathological cases, is worse than traditional Earley parsing, but it's an
+//! easier fit for Macro-by-Example-style rules, and I think the overhead is
+//! lower. (In order to prevent the pathological case, we'd need to lazily
+//! construct the resulting `NamedMatch`es at the very end. It'd be a pain,
+//! and require more memory to keep around old items, but it would also save
+//! overhead)
+//!
+//! Quick intro to how the parser works:
+//!
+//! A 'position' is a dot in the middle of a matcher, usually represented as a
+//! dot. For example `· a $( a )* a b` is a position, as is `a $( · a )* a b`.
+//!
+//! The parser walks through the input a character at a time, maintaining a list
+//! of items consistent with the current position in the input string: `cur_eis`.
+//!
+//! As it processes them, it fills up `eof_eis` with items that would be valid if
+//! the macro invocation is now over, `bb_eis` with items that are waiting on
+//! a Rust nonterminal like `$e:expr`, and `next_eis` with items that are waiting
+//! on the a particular token. Most of the logic concerns moving the · through the
+//! repetitions indicated by Kleene stars. It only advances or calls out to the
+//! real Rust parser when no `cur_eis` items remain
+//!
+//! Example: Start parsing `a a a a b` against [· a $( a )* a b].
+//!
+//! Remaining input: `a a a a b`
+//! next_eis: [· a $( a )* a b]
+//!
+//! - - - Advance over an `a`. - - -
+//!
+//! Remaining input: `a a a b`
+//! cur: [a · $( a )* a b]
+//! Descend/Skip (first item).
+//! next: [a $( · a )* a b] [a $( a )* · a b].
+//!
+//! - - - Advance over an `a`. - - -
+//!
+//! Remaining input: `a a b`
+//! cur: [a $( a · )* a b] next: [a $( a )* a · b]
+//! Finish/Repeat (first item)
+//! next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b]
+//!
+//! - - - Advance over an `a`. - - - (this looks exactly like the last step)
+//!
+//! Remaining input: `a b`
+//! cur: [a $( a · )* a b] next: [a $( a )* a · b]
+//! Finish/Repeat (first item)
+//! next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b]
+//!
+//! - - - Advance over an `a`. - - - (this looks exactly like the last step)
+//!
+//! Remaining input: `b`
+//! cur: [a $( a · )* a b] next: [a $( a )* a · b]
+//! Finish/Repeat (first item)
+//! next: [a $( a )* · a b] [a $( · a )* a b]
+//!
+//! - - - Advance over a `b`. - - -
+//!
+//! Remaining input: ``
+//! eof: [a $( a )* a b ·]
+
use ast;
use ast::{Matcher, MatchTok, MatchSeq, MatchNonterminal, Ident};
use std::gc::GC;
use std::collections::HashMap;
-/* This is an Earley-like parser, without support for in-grammar nonterminals,
-only by calling out to the main rust parser for named nonterminals (which it
-commits to fully when it hits one in a grammar). This means that there are no
-completer or predictor rules, and therefore no need to store one column per
-token: instead, there's a set of current Earley items and a set of next
-ones. Instead of NTs, we have a special case for Kleene star. The big-O, in
-pathological cases, is worse than traditional Earley parsing, but it's an
-easier fit for Macro-by-Example-style rules, and I think the overhead is
-lower. (In order to prevent the pathological case, we'd need to lazily
-construct the resulting `NamedMatch`es at the very end. It'd be a pain,
-and require more memory to keep around old items, but it would also save
-overhead)*/
-
-/* Quick intro to how the parser works:
-
-A 'position' is a dot in the middle of a matcher, usually represented as a
-dot. For example `· a $( a )* a b` is a position, as is `a $( · a )* a b`.
-
-The parser walks through the input a character at a time, maintaining a list
-of items consistent with the current position in the input string: `cur_eis`.
-
-As it processes them, it fills up `eof_eis` with items that would be valid if
-the macro invocation is now over, `bb_eis` with items that are waiting on
-a Rust nonterminal like `$e:expr`, and `next_eis` with items that are waiting
-on the a particular token. Most of the logic concerns moving the · through the
-repetitions indicated by Kleene stars. It only advances or calls out to the
-real Rust parser when no `cur_eis` items remain
-
-Example: Start parsing `a a a a b` against [· a $( a )* a b].
-
-Remaining input: `a a a a b`
-next_eis: [· a $( a )* a b]
-
-- - - Advance over an `a`. - - -
-
-Remaining input: `a a a b`
-cur: [a · $( a )* a b]
-Descend/Skip (first item).
-next: [a $( · a )* a b] [a $( a )* · a b].
-
-- - - Advance over an `a`. - - -
-
-Remaining input: `a a b`
-cur: [a $( a · )* a b] next: [a $( a )* a · b]
-Finish/Repeat (first item)
-next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b]
-
-- - - Advance over an `a`. - - - (this looks exactly like the last step)
-
-Remaining input: `a b`
-cur: [a $( a · )* a b] next: [a $( a )* a · b]
-Finish/Repeat (first item)
-next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b]
-
-- - - Advance over an `a`. - - - (this looks exactly like the last step)
-
-Remaining input: `b`
-cur: [a $( a · )* a b] next: [a $( a )* a · b]
-Finish/Repeat (first item)
-next: [a $( a )* · a b] [a $( · a )* a b]
-
-- - - Advance over a `b`. - - -
-
-Remaining input: ``
-eof: [a $( a )* a b ·]
-
- */
-
-
/* to avoid costly uniqueness checks, we require that `MatchSeq` always has a
nonempty body. */
}
}
-// NamedMatch is a pattern-match result for a single ast::MatchNonterminal:
-// so it is associated with a single ident in a parse, and all
-// MatchedNonterminal's in the NamedMatch have the same nonterminal type
-// (expr, item, etc). All the leaves in a single NamedMatch correspond to a
-// single matcher_nonterminal in the ast::Matcher that produced it.
-//
-// It should probably be renamed, it has more or less exact correspondence to
-// ast::match nodes, and the in-memory structure of a particular NamedMatch
-// represents the match that occurred when a particular subset of an
-// ast::match -- those ast::Matcher nodes leading to a single
-// MatchNonterminal -- was applied to a particular token tree.
-//
-// The width of each MatchedSeq in the NamedMatch, and the identity of the
-// MatchedNonterminal's, will depend on the token tree it was applied to: each
-// MatchedSeq corresponds to a single MatchSeq in the originating
-// ast::Matcher. The depth of the NamedMatch structure will therefore depend
-// only on the nesting depth of ast::MatchSeq's in the originating
-// ast::Matcher it was derived from.
+/// NamedMatch is a pattern-match result for a single ast::MatchNonterminal:
+/// so it is associated with a single ident in a parse, and all
+/// MatchedNonterminal's in the NamedMatch have the same nonterminal type
+/// (expr, item, etc). All the leaves in a single NamedMatch correspond to a
+/// single matcher_nonterminal in the ast::Matcher that produced it.
+///
+/// It should probably be renamed, it has more or less exact correspondence to
+/// ast::match nodes, and the in-memory structure of a particular NamedMatch
+/// represents the match that occurred when a particular subset of an
+/// ast::match -- those ast::Matcher nodes leading to a single
+/// MatchNonterminal -- was applied to a particular token tree.
+///
+/// The width of each MatchedSeq in the NamedMatch, and the identity of the
+/// MatchedNonterminal's, will depend on the token tree it was applied to: each
+/// MatchedSeq corresponds to a single MatchSeq in the originating
+/// ast::Matcher. The depth of the NamedMatch structure will therefore depend
+/// only on the nesting depth of ast::MatchSeq's in the originating
+/// ast::Matcher it was derived from.
pub enum NamedMatch {
MatchedSeq(Vec<Rc<NamedMatch>>, codemap::Span),
}
}
-// perform a token equality check, ignoring syntax context (that is, an unhygienic comparison)
+/// Perform a token equality check, ignoring syntax context (that is, an
+/// unhygienic comparison)
pub fn token_name_eq(t1 : &Token, t2 : &Token) -> bool {
match (t1,t2) {
(&token::IDENT(id1,_),&token::IDENT(id2,_))
MatchNonterminal(_,_,_) => { bb_eis.push(ei) }
MatchTok(ref t) => {
let mut ei_t = ei.clone();
- //if (token_name_eq(t,&tok)) {
- if token::mtwt_token_eq(t,&tok) {
+ if token_name_eq(t,&tok) {
ei_t.idx += 1;
next_eis.push(ei_t);
}
nts, next_eis.len()).to_string());
} else if bb_eis.len() == 0u && next_eis.len() == 0u {
return Failure(sp, format!("no rules expected the token `{}`",
- token::to_str(&tok)).to_string());
+ token::to_string(&tok)).to_string());
} else if next_eis.len() > 0u {
/* Now process the next token */
while next_eis.len() > 0u {
"ident" => match p.token {
token::IDENT(sn,b) => { p.bump(); token::NtIdent(box sn,b) }
_ => {
- let token_str = token::to_str(&p.token);
+ let token_str = token::to_string(&p.token);
p.fatal((format!("expected ident, found {}",
token_str.as_slice())).as_slice())
}
use ast;
use codemap::{Span, Spanned, DUMMY_SP};
use ext::base::{ExtCtxt, MacResult, MacroDef};
-use ext::base::{NormalTT, MacroExpander};
+use ext::base::{NormalTT, TTMacroExpander};
use ext::base;
use ext::tt::macro_parser::{Success, Error, Failure};
use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
impl<'a> ParserAnyMacro<'a> {
/// Make sure we don't have any tokens left to parse, so we don't
/// silently drop anything. `allow_semi` is so that "optional"
- /// semilons at the end of normal expressions aren't complained
+ /// semicolons at the end of normal expressions aren't complained
/// about e.g. the semicolon in `macro_rules! kapow( () => {
/// fail!(); } )` doesn't get picked up by .parse_expr(), but it's
/// allowed to be there.
parser.bump()
}
if parser.token != EOF {
- let token_str = parser.this_token_to_str();
+ let token_str = parser.this_token_to_string();
let msg = format!("macro expansion ignores token `{}` and any \
following",
token_str);
let mut ret = SmallVector::zero();
loop {
let mut parser = self.parser.borrow_mut();
+ // so... do outer attributes attached to the macro invocation
+ // just disappear? This question applies to make_methods, as
+ // well.
match parser.parse_item_with_outer_attributes() {
Some(item) => ret.push(item),
None => break
self.ensure_complete_parse(false);
Some(ret)
}
+
+ fn make_methods(&self) -> Option<SmallVector<Gc<ast::Method>>> {
+ let mut ret = SmallVector::zero();
+ loop {
+ let mut parser = self.parser.borrow_mut();
+ match parser.token {
+ EOF => break,
+ _ => ret.push(parser.parse_method(None))
+ }
+ }
+ self.ensure_complete_parse(false);
+ Some(ret)
+ }
+
fn make_stmt(&self) -> Option<Gc<ast::Stmt>> {
let attrs = self.parser.borrow_mut().parse_outer_attributes();
let ret = self.parser.borrow_mut().parse_stmt(attrs);
rhses: Vec<Rc<NamedMatch>>,
}
-impl MacroExpander for MacroRulesMacroExpander {
+impl TTMacroExpander for MacroRulesMacroExpander {
fn expand(&self,
cx: &mut ExtCtxt,
sp: Span,
}
}
-// Given `lhses` and `rhses`, this is the new macro we create
+/// Given `lhses` and `rhses`, this is the new macro we create
fn generic_extension(cx: &ExtCtxt,
sp: Span,
name: Ident,
println!("{}! {} {} {}",
token::get_ident(name),
"{",
- print::pprust::tt_to_str(&TTDelim(Rc::new(arg.iter()
+ print::pprust::tt_to_string(&TTDelim(Rc::new(arg.iter()
.map(|x| (*x).clone())
.collect()))),
"}");
cx.span_fatal(best_fail_spot, best_fail_msg.as_slice());
}
-// this procedure performs the expansion of the
-// macro_rules! macro. It parses the RHS and adds
-// an extension to the current context.
+/// This procedure performs the expansion of the
+/// macro_rules! macro. It parses the RHS and adds
+/// an extension to the current context.
pub fn add_new_extension(cx: &mut ExtCtxt,
sp: Span,
name: Ident,
box MacroRulesDefiner {
def: RefCell::new(Some(MacroDef {
- name: token::get_ident(name).to_str(),
+ name: token::get_ident(name).to_string(),
ext: NormalTT(exp, Some(sp))
}))
} as Box<MacResult>
#[deriving(Clone)]
pub struct TtReader<'a> {
pub sp_diag: &'a SpanHandler,
- // the unzipped tree:
+ /// the unzipped tree:
stack: Vec<TtFrame>,
/* for MBE-style macro transcription */
interpolations: HashMap<Ident, Rc<NamedMatch>>,
pub cur_span: Span,
}
-/** This can do Macro-By-Example transcription. On the other hand, if
- * `src` contains no `TTSeq`s and `TTNonterminal`s, `interp` can (and
- * should) be none. */
+/// This can do Macro-By-Example transcription. On the other hand, if
+/// `src` contains no `TTSeq`s and `TTNonterminal`s, `interp` can (and
+/// should) be none.
pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
interp: Option<HashMap<Ident, Rc<NamedMatch>>>,
src: Vec<ast::TokenTree> )
}
}
-// return the next token from the TtReader.
-// EFFECT: advances the reader's token field
+/// Return the next token from the TtReader.
+/// EFFECT: advances the reader's token field
pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
// FIXME(pcwalton): Bad copy?
let ret_val = TokenAndSpan {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+//! A Folder represents an AST->AST fold; it accepts an AST piece,
+//! and returns a piece of the same type. So, for instance, macro
+//! expansion is a Folder that walks over an AST and produces another
+//! AST.
+//!
+//! Note: using a Folder (other than the MacroExpander Folder) on
+//! an AST before macro expansion is probably a bad idea. For instance,
+//! a folder renaming item names in a module will miss all of those
+//! that are created by the expansion of a macro.
+
use ast::*;
use ast;
use ast_util;
noop_fold_type_method(m, self)
}
- fn fold_method(&mut self, m: Gc<Method>) -> Gc<Method> {
+ fn fold_method(&mut self, m: Gc<Method>) -> SmallVector<Gc<Method>> {
noop_fold_method(&*m, self)
}
}
}
- fn fold_mac(&mut self, macro: &Mac) -> Mac {
- Spanned {
- node: match macro.node {
- MacInvocTT(ref p, ref tts, ctxt) => {
- MacInvocTT(self.fold_path(p),
- fold_tts(tts.as_slice(), self),
- ctxt)
- }
- },
- span: self.new_span(macro.span)
- }
+ fn fold_mac(&mut self, _macro: &Mac) -> Mac {
+ fail!("fold_mac disabled by default");
+ // NB: see note about macros above.
+ // if you really want a folder that
+ // works on macros, use this
+ // definition in your trait impl:
+ // fold::fold_mac(_macro, self)
}
fn map_exprs(&self, f: |Gc<Expr>| -> Gc<Expr>,
fn fold_explicit_self_(&mut self, es: &ExplicitSelf_) -> ExplicitSelf_ {
match *es {
- SelfStatic | SelfValue | SelfUniq => *es,
- SelfRegion(ref lifetime, m) => {
- SelfRegion(fold_opt_lifetime(lifetime, self), m)
+ SelfStatic | SelfValue(_) | SelfUniq(_) => *es,
+ SelfRegion(ref lifetime, m, id) => {
+ SelfRegion(fold_opt_lifetime(lifetime, self), m, id)
}
}
}
}
+
+pub fn fold_mac<T: Folder>(macro: &Mac, fld: &mut T) -> Mac {
+ Spanned {
+ node: match macro.node {
+ MacInvocTT(ref p, ref tts, ctxt) => {
+ MacInvocTT(fld.fold_path(p),
+ fold_tts(tts.as_slice(), fld),
+ ctxt)
+ }
+ },
+ span: fld.new_span(macro.span)
+ }
+}
+
/* some little folds that probably aren't useful to have in Folder itself*/
//used in noop_fold_item and noop_fold_crate and noop_fold_crate_directive
match *nt {
token::NtItem(item) =>
token::NtItem(fld.fold_item(item)
+ // this is probably okay, because the only folds likely
+ // to peek inside interpolated nodes will be renamings/markings,
+ // which map single items to single items
.expect_one("expected fold to produce exactly one item")),
token::NtBlock(block) => token::NtBlock(fld.fold_block(block)),
token::NtStmt(stmt) =>
token::NtStmt(fld.fold_stmt(stmt)
+ // this is probably okay, because the only folds likely
+ // to peek inside interpolated nodes will be renamings/markings,
+ // which map single items to single items
.expect_one("expected fold to produce exactly one statement")),
token::NtPat(pat) => token::NtPat(fld.fold_pat(pat)),
token::NtExpr(expr) => token::NtExpr(fld.fold_expr(expr)),
TyParam {
ident: tp.ident,
id: id,
- sized: tp.sized,
bounds: tp.bounds.map(|x| fold_ty_param_bound(x, fld)),
+ unbound: tp.unbound.as_ref().map(|x| fold_ty_param_bound(x, fld)),
default: tp.default.map(|x| fld.fold_ty(x)),
span: tp.span
}
ItemImpl(fold_generics(generics, folder),
ifce.as_ref().map(|p| fold_trait_ref(p, folder)),
folder.fold_ty(ty),
- methods.iter().map(|x| folder.fold_method(*x)).collect()
+ methods.iter().flat_map(|x| folder.fold_method(*x).move_iter()).collect()
)
}
- ItemTrait(ref generics, ref sized, ref traits, ref methods) => {
- let methods = methods.iter().map(|method| {
- match *method {
- Required(ref m) => Required(folder.fold_type_method(m)),
- Provided(method) => Provided(folder.fold_method(method))
- }
+ ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
+ let methods = methods.iter().flat_map(|method| {
+ let r = match *method {
+ Required(ref m) =>
+ SmallVector::one(Required(folder.fold_type_method(m))).move_iter(),
+ Provided(method) => {
+ // the awkward collect/iter idiom here is because
+ // even though an iter and a map satisfy the same trait bound,
+ // they're not actually the same type, so the method arms
+ // don't unify.
+ let methods : SmallVector<ast::TraitMethod> =
+ folder.fold_method(method).move_iter()
+ .map(|m| Provided(m)).collect();
+ methods.move_iter()
+ }
+ };
+ r
}).collect();
ItemTrait(fold_generics(generics, folder),
- *sized,
+ unbound.clone(),
traits.iter().map(|p| fold_trait_ref(p, folder)).collect(),
methods)
}
attrs: c.attrs.iter().map(|x| folder.fold_attribute(*x)).collect(),
config: c.config.iter().map(|x| fold_meta_item_(*x, folder)).collect(),
span: folder.new_span(c.span),
+ exported_macros: c.exported_macros.iter().map(|sp| folder.new_span(*sp)).collect(),
}
}
}
}
-pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> Gc<Method> {
+// Default fold over a method.
+// Invariant: produces exactly one method.
+pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> SmallVector<Gc<Method>> {
let id = folder.new_id(m.id); // Needs to be first, for ast_map.
- box(GC) Method {
- id: id,
- ident: folder.fold_ident(m.ident),
+ SmallVector::one(box(GC) Method {
attrs: m.attrs.iter().map(|a| folder.fold_attribute(*a)).collect(),
- generics: fold_generics(&m.generics, folder),
- explicit_self: folder.fold_explicit_self(&m.explicit_self),
- fn_style: m.fn_style,
- decl: folder.fold_fn_decl(&*m.decl),
- body: folder.fold_block(m.body),
+ id: id,
span: folder.new_span(m.span),
- vis: m.vis
- }
+ node: match m.node {
+ MethDecl(ident, ref generics, ref explicit_self, fn_style, decl, body, vis) => {
+ MethDecl(folder.fold_ident(ident),
+ fold_generics(generics, folder),
+ folder.fold_explicit_self(explicit_self),
+ fn_style,
+ folder.fold_fn_decl(&*decl),
+ folder.fold_block(body),
+ vis)
+ },
+ MethMac(ref mac) => MethMac(folder.fold_mac(mac)),
+ }
+ })
}
pub fn noop_fold_pat<T: Folder>(p: Gc<Pat>, folder: &mut T) -> Gc<Pat> {
PatIdent(binding_mode, ref pth1, ref sub) => {
PatIdent(binding_mode,
Spanned{span: folder.new_span(pth1.span),
- node: folder.fold_ident(pth1.node)},
+ node: folder.fold_ident(pth1.node)},
sub.map(|x| folder.fold_pat(x)))
}
PatLit(e) => PatLit(folder.fold_expr(e)),
use util::parser_testing::{string_to_crate, matches_codepattern};
use parse::token;
use print::pprust;
+ use fold;
use super::*;
// this version doesn't care about getting comments or docstrings in.
fn fold_ident(&mut self, _: ast::Ident) -> ast::Ident {
token::str_to_ident("zz")
}
+ fn fold_mac(&mut self, macro: &ast::Mac) -> ast::Mac {
+ fold::fold_mac(macro, self)
+ }
}
// maybe add to expand.rs...
assert_pred!(
matches_codepattern,
"matches_codepattern",
- pprust::to_str(|s| fake_print_crate(s, &folded_crate)),
+ pprust::to_string(|s| fake_print_crate(s, &folded_crate)),
"#[a]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_string());
}
assert_pred!(
matches_codepattern,
"matches_codepattern",
- pprust::to_str(|s| fake_print_crate(s, &folded_crate)),
+ pprust::to_string(|s| fake_print_crate(s, &folded_crate)),
"zz!zz((zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+)))".to_string());
}
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-/*!
+//! The Rust parser and macro expander.
+//!
+//! # Note
+//!
+//! This API is completely unstable and subject to change.
-The Rust parser and macro expander.
-
-# Note
-
-This API is completely unstable and subject to change.
-
-*/
-
-#![crate_id = "syntax#0.11.0"]
+#![crate_name = "syntax"]
#![experimental]
#![license = "MIT/ASL2"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+ html_root_url = "http://doc.rust-lang.org/master/")]
#![feature(macro_rules, globs, managed_boxes, default_type_params, phase)]
#![feature(quote, unsafe_destructor)]
#![allow(deprecated)]
-extern crate serialize;
-extern crate term;
-#[phase(plugin, link)] extern crate log;
-
extern crate fmt_macros;
extern crate debug;
+#[phase(plugin, link)] extern crate log;
+extern crate serialize;
+extern crate term;
pub mod util {
pub mod interner;
pub mod small_vector;
}
+pub mod diagnostics {
+ pub mod macros;
+ pub mod plugin;
+ pub mod registry;
+}
+
pub mod syntax {
pub use ext;
pub use parse;
pub use ast;
}
-pub mod owned_slice;
-pub mod attr;
-pub mod diagnostic;
-pub mod codemap;
pub mod abi;
pub mod ast;
-pub mod ast_util;
pub mod ast_map;
-pub mod visit;
+pub mod ast_util;
+pub mod attr;
+pub mod codemap;
+pub mod crateid;
+pub mod diagnostic;
pub mod fold;
-
-
+pub mod owned_slice;
pub mod parse;
-pub mod crateid;
+pub mod visit;
pub mod print {
pub mod pp;
pub mod ext {
pub mod asm;
pub mod base;
+ pub mod build;
+ pub mod bytes;
+ pub mod cfg;
+ pub mod concat;
+ pub mod concat_idents;
+ pub mod deriving;
+ pub mod env;
pub mod expand;
-
+ pub mod fmt;
+ pub mod format;
+ pub mod log_syntax;
+ pub mod mtwt;
pub mod quote;
-
- pub mod deriving;
-
- pub mod build;
+ pub mod source_util;
+ pub mod trace_macros;
pub mod tt {
pub mod transcribe;
pub mod macro_parser;
pub mod macro_rules;
}
-
- pub mod mtwt;
-
- pub mod cfg;
- pub mod fmt;
- pub mod format;
- pub mod env;
- pub mod bytes;
- pub mod concat;
- pub mod concat_idents;
- pub mod log_syntax;
- pub mod source_util;
-
- pub mod trace_macros;
}
use std::gc::{Gc, GC};
-// a parser that can parse attributes.
+/// A parser that can parse attributes.
pub trait ParserAttr {
fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute>;
fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute;
}
impl<'a> ParserAttr for Parser<'a> {
- // Parse attributes that appear before an item
+ /// Parse attributes that appear before an item
fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute> {
let mut attrs: Vec<ast::Attribute> = Vec::new();
loop {
- debug!("parse_outer_attributes: self.token={:?}",
+ debug!("parse_outer_attributes: self.token={}",
self.token);
match self.token {
token::POUND => {
token::DOC_COMMENT(s) => {
let attr = ::attr::mk_sugared_doc_attr(
attr::mk_attr_id(),
- self.id_to_interned_str(s),
+ self.id_to_interned_str(s.ident()),
self.span.lo,
self.span.hi
);
return attrs;
}
- // matches attribute = # ! [ meta_item ]
- //
- // if permit_inner is true, then a leading `!` indicates an inner
- // attribute
+ /// Matches `attribute = # ! [ meta_item ]`
+ ///
+ /// If permit_inner is true, then a leading `!` indicates an inner
+ /// attribute
fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute {
debug!("parse_attributes: permit_inner={:?} self.token={:?}",
permit_inner, self.token);
self.expect(&token::LBRACKET);
let meta_item = self.parse_meta_item();
+ let hi = self.span.hi;
self.expect(&token::RBRACKET);
- let hi = self.span.hi;
(mk_sp(lo, hi), meta_item, style)
}
_ => {
- let token_str = self.this_token_to_str();
+ let token_str = self.this_token_to_string();
self.fatal(format!("expected `#` but found `{}`",
token_str).as_slice());
}
};
}
- // Parse attributes that appear after the opening of an item. These should
- // be preceded by an exclamation mark, but we accept and warn about one
- // terminated by a semicolon. In addition to a vector of inner attributes,
- // this function also returns a vector that may contain the first outer
- // attribute of the next item (since we can't know whether the attribute
- // is an inner attribute of the containing item or an outer attribute of
- // the first contained item until we see the semi).
-
- // matches inner_attrs* outer_attr?
- // you can make the 'next' field an Option, but the result is going to be
- // more useful as a vector.
+ /// Parse attributes that appear after the opening of an item. These should
+ /// be preceded by an exclamation mark, but we accept and warn about one
+ /// terminated by a semicolon. In addition to a vector of inner attributes,
+ /// this function also returns a vector that may contain the first outer
+ /// attribute of the next item (since we can't know whether the attribute
+ /// is an inner attribute of the containing item or an outer attribute of
+ /// the first contained item until we see the semi).
+
+ /// matches inner_attrs* outer_attr?
+ /// you can make the 'next' field an Option, but the result is going to be
+ /// more useful as a vector.
fn parse_inner_attrs_and_next(&mut self)
-> (Vec<ast::Attribute> , Vec<ast::Attribute> ) {
let mut inner_attrs: Vec<ast::Attribute> = Vec::new();
let Span { lo, hi, .. } = self.span;
self.bump();
attr::mk_sugared_doc_attr(attr::mk_attr_id(),
- self.id_to_interned_str(s),
+ self.id_to_interned_str(s.ident()),
lo,
hi)
}
(inner_attrs, next_outer_attrs)
}
- // matches meta_item = IDENT
- // | IDENT = lit
- // | IDENT meta_seq
+ /// matches meta_item = IDENT
+ /// | IDENT = lit
+ /// | IDENT meta_seq
fn parse_meta_item(&mut self) -> Gc<ast::MetaItem> {
match self.token {
token::INTERPOLATED(token::NtMeta(e)) => {
}
}
- // matches meta_seq = ( COMMASEP(meta_item) )
+ /// matches meta_seq = ( COMMASEP(meta_item) )
fn parse_meta_seq(&mut self) -> Vec<Gc<ast::MetaItem>> {
self.parse_seq(&token::LPAREN,
&token::RPAREN,
use ast;
use std::gc::Gc;
-// does this expression require a semicolon to be treated
-// as a statement? The negation of this: 'can this expression
-// be used as a statement without a semicolon' -- is used
-// as an early-bail-out in the parser so that, for instance,
-// 'if true {...} else {...}
-// |x| 5 '
-// isn't parsed as (if true {...} else {...} | x) | 5
+/// Does this expression require a semicolon to be treated
+/// as a statement? The negation of this: 'can this expression
+/// be used as a statement without a semicolon' -- is used
+/// as an early-bail-out in the parser so that, for instance,
+/// if true {...} else {...}
+/// |x| 5
+/// isn't parsed as (if true {...} else {...} | x) | 5
pub fn expr_requires_semi_to_be_stmt(e: Gc<ast::Expr>) -> bool {
match e.node {
ast::ExprIf(..)
}
}
-// this statement requires a semicolon after it.
-// note that in one case (stmt_semi), we've already
-// seen the semicolon, and thus don't need another.
+/// this statement requires a semicolon after it.
+/// note that in one case (stmt_semi), we've already
+/// seen the semicolon, and thus don't need another.
pub fn stmt_ends_with_semi(stmt: &ast::Stmt) -> bool {
return match stmt.node {
ast::StmtDecl(d, _) => {
use parse::token;
-// SeqSep : a sequence separator (token)
-// and whether a trailing separator is allowed.
+/// SeqSep : a sequence separator (token)
+/// and whether a trailing separator is allowed.
pub struct SeqSep {
pub sep: Option<token::Token>,
pub trailing_sep_allowed: bool
use diagnostic;
use parse::lexer::{is_whitespace, Reader};
use parse::lexer::{StringReader, TokenAndSpan};
-use parse::lexer::{is_line_non_doc_comment, is_block_non_doc_comment};
+use parse::lexer::is_block_doc_comment;
use parse::lexer;
use parse::token;
#[deriving(Clone, PartialEq)]
pub enum CommentStyle {
- Isolated, // No code on either side of each line of the comment
- Trailing, // Code exists to the left of the comment
- Mixed, // Code before /* foo */ and after the comment
- BlankLine, // Just a manual blank line "\n\n", for layout
+ /// No code on either side of each line of the comment
+ Isolated,
+ /// Code exists to the left of the comment
+ Trailing,
+ /// Code before /* foo */ and after the comment
+ Mixed,
+ /// Just a manual blank line "\n\n", for layout
+ BlankLine,
}
#[deriving(Clone)]
}
pub fn is_doc_comment(s: &str) -> bool {
- (s.starts_with("///") && !is_line_non_doc_comment(s)) ||
+ (s.starts_with("///") && super::is_doc_comment(s)) ||
s.starts_with("//!") ||
- (s.starts_with("/**") && !is_block_non_doc_comment(s)) ||
+ (s.starts_with("/**") && is_block_doc_comment(s)) ||
s.starts_with("/*!")
}
}
}
-// Returns None if the first col chars of s contain a non-whitespace char.
-// Otherwise returns Some(k) where k is first char offset after that leading
-// whitespace. Note k may be outside bounds of s.
+/// Returns None if the first col chars of s contain a non-whitespace char.
+/// Otherwise returns Some(k) where k is first char offset after that leading
+/// whitespace. Note k may be outside bounds of s.
fn all_whitespace(s: &str, col: CharPos) -> Option<uint> {
let len = s.len();
let mut col = col.to_uint();
rdr.bump();
rdr.bump();
}
- if !is_block_non_doc_comment(curr_line.as_slice()) {
+ if is_block_doc_comment(curr_line.as_slice()) {
return
}
assert!(!curr_line.as_slice().contains_char('\n'));
literals.push(Literal {lit: s.to_string(), pos: sp.lo});
})
} else {
- debug!("tok: {}", token::to_str(&tok));
+ debug!("tok: {}", token::to_string(&tok));
}
first_read = false;
}
use std::char;
use std::mem::replace;
-use std::num::from_str_radix;
use std::rc::Rc;
use std::str;
pub struct StringReader<'a> {
pub span_diagnostic: &'a SpanHandler,
- // The absolute offset within the codemap of the next character to read
+ /// The absolute offset within the codemap of the next character to read
pub pos: BytePos,
- // The absolute offset within the codemap of the last character read(curr)
+ /// The absolute offset within the codemap of the last character read(curr)
pub last_pos: BytePos,
- // The column of the next character to read
+ /// The column of the next character to read
pub col: CharPos,
- // The last character to be read
+ /// The last character to be read
pub curr: Option<char>,
pub filemap: Rc<codemap::FileMap>,
/* cached: */
impl<'a> Reader for StringReader<'a> {
fn is_eof(&self) -> bool { self.curr.is_none() }
- // return the next token. EFFECT: advances the string_reader.
+ /// Return the next token. EFFECT: advances the string_reader.
fn next_token(&mut self) -> TokenAndSpan {
let ret_val = TokenAndSpan {
tok: replace(&mut self.peek_tok, token::UNDERSCORE),
}
fn next_token(&mut self) -> TokenAndSpan {
let r = tt_next_token(self);
- debug!("TtReader: r={:?}", r);
+ debug!("TtReader: r={}", r);
r
}
fn fatal(&self, m: &str) -> ! {
/// Advance peek_tok and peek_span to refer to the next token, and
/// possibly update the interner.
fn advance_token(&mut self) {
- match self.consume_whitespace_and_comments() {
+ match self.scan_whitespace_or_comment() {
Some(comment) => {
self.peek_span = comment.sp;
self.peek_tok = comment.tok;
self.with_str_from_to(start, self.last_pos, f)
}
+ /// Create a Name from a given offset to the current offset, each
+ /// adjusted 1 towards each other (assumes that on either side there is a
+ /// single-byte delimiter).
+ pub fn name_from(&self, start: BytePos) -> ast::Name {
+ debug!("taking an ident from {} to {}", start, self.last_pos);
+ self.with_str_from(start, token::intern)
+ }
+
+ /// As name_from, with an explicit endpoint.
+ pub fn name_from_to(&self, start: BytePos, end: BytePos) -> ast::Name {
+ debug!("taking an ident from {} to {}", start, end);
+ self.with_str_from_to(start, end, token::intern)
+ }
+
/// Calls `f` with a string slice of the source text spanning from `start`
/// up to but excluding `end`.
fn with_str_from_to<T>(&self, start: BytePos, end: BytePos, f: |s: &str| -> T) -> T {
/// PRECONDITION: self.curr is not whitespace
/// Eats any kind of comment.
- /// Returns a Some(sugared-doc-attr) if one exists, None otherwise
- fn consume_any_line_comment(&mut self) -> Option<TokenAndSpan> {
+ fn scan_comment(&mut self) -> Option<TokenAndSpan> {
match self.curr {
Some(c) => {
if c.is_whitespace() {
}
self.bump();
}
- let ret = self.with_str_from(start_bpos, |string| {
+ return self.with_str_from(start_bpos, |string| {
// but comments with only more "/"s are not
- if !is_line_non_doc_comment(string) {
- Some(TokenAndSpan{
- tok: token::DOC_COMMENT(str_to_ident(string)),
- sp: codemap::mk_sp(start_bpos, self.last_pos)
- })
+ let tok = if is_doc_comment(string) {
+ token::DOC_COMMENT(token::intern(string))
} else {
- None
- }
- });
+ token::COMMENT
+ };
- if ret.is_some() {
- return ret;
- }
+ return Some(TokenAndSpan{
+ tok: tok,
+ sp: codemap::mk_sp(start_bpos, self.last_pos)
+ });
+ });
} else {
+ let start_bpos = self.last_pos - BytePos(2);
while !self.curr_is('\n') && !self.is_eof() { self.bump(); }
+ return Some(TokenAndSpan {
+ tok: token::COMMENT,
+ sp: codemap::mk_sp(start_bpos, self.last_pos)
+ });
}
- // Restart whitespace munch.
- self.consume_whitespace_and_comments()
}
- Some('*') => { self.bump(); self.bump(); self.consume_block_comment() }
+ Some('*') => {
+ self.bump(); self.bump();
+ self.scan_block_comment()
+ }
_ => None
}
} else if self.curr_is('#') {
let cmap = CodeMap::new();
cmap.files.borrow_mut().push(self.filemap.clone());
let loc = cmap.lookup_char_pos_adj(self.last_pos);
+ debug!("Skipping a shebang");
if loc.line == 1u && loc.col == CharPos(0u) {
+ // FIXME: Add shebang "token", return it
+ let start = self.last_pos;
while !self.curr_is('\n') && !self.is_eof() { self.bump(); }
- return self.consume_whitespace_and_comments();
+ return Some(TokenAndSpan {
+ tok: token::SHEBANG(self.name_from(start)),
+ sp: codemap::mk_sp(start, self.last_pos)
+ });
}
}
None
}
}
- /// EFFECT: eats whitespace and comments.
- /// Returns a Some(sugared-doc-attr) if one exists, None otherwise.
- fn consume_whitespace_and_comments(&mut self) -> Option<TokenAndSpan> {
- while is_whitespace(self.curr) { self.bump(); }
- return self.consume_any_line_comment();
+ /// If there is whitespace, shebang, or a comment, scan it. Otherwise,
+ /// return None.
+ fn scan_whitespace_or_comment(&mut self) -> Option<TokenAndSpan> {
+ match self.curr.unwrap_or('\0') {
+ // # to handle shebang at start of file -- this is the entry point
+ // for skipping over all "junk"
+ '/' | '#' => {
+ let c = self.scan_comment();
+ debug!("scanning a comment {}", c);
+ c
+ },
+ c if is_whitespace(Some(c)) => {
+ let start_bpos = self.last_pos;
+ while is_whitespace(self.curr) { self.bump(); }
+ let c = Some(TokenAndSpan {
+ tok: token::WS,
+ sp: codemap::mk_sp(start_bpos, self.last_pos)
+ });
+ debug!("scanning whitespace: {}", c);
+ c
+ },
+ _ => None
+ }
}
- // might return a sugared-doc-attr
- fn consume_block_comment(&mut self) -> Option<TokenAndSpan> {
+ /// Might return a sugared-doc-attr
+ fn scan_block_comment(&mut self) -> Option<TokenAndSpan> {
// block comments starting with "/**" or "/*!" are doc-comments
let is_doc_comment = self.curr_is('*') || self.curr_is('!');
let start_bpos = self.last_pos - BytePos(2);
self.bump();
}
- let res = if is_doc_comment {
- self.with_str_from(start_bpos, |string| {
- // but comments with only "*"s between two "/"s are not
- if !is_block_non_doc_comment(string) {
- let string = if has_cr {
- self.translate_crlf(start_bpos, string,
- "bare CR not allowed in block doc-comment")
- } else { string.into_maybe_owned() };
- Some(TokenAndSpan{
- tok: token::DOC_COMMENT(str_to_ident(string.as_slice())),
- sp: codemap::mk_sp(start_bpos, self.last_pos)
- })
- } else {
- None
- }
- })
- } else {
- None
- };
-
- // restart whitespace munch.
- if res.is_some() { res } else { self.consume_whitespace_and_comments() }
- }
-
- fn scan_exponent(&mut self, start_bpos: BytePos) -> Option<String> {
- // \x00 hits the `return None` case immediately, so this is fine.
- let mut c = self.curr.unwrap_or('\x00');
- let mut rslt = String::new();
- if c == 'e' || c == 'E' {
- rslt.push_char(c);
- self.bump();
- c = self.curr.unwrap_or('\x00');
- if c == '-' || c == '+' {
- rslt.push_char(c);
- self.bump();
- }
- let exponent = self.scan_digits(10u);
- if exponent.len() > 0u {
- rslt.push_str(exponent.as_slice());
- return Some(rslt);
+ self.with_str_from(start_bpos, |string| {
+ // but comments with only "*"s between two "/"s are not
+ let tok = if is_block_doc_comment(string) {
+ let string = if has_cr {
+ self.translate_crlf(start_bpos, string,
+ "bare CR not allowed in block doc-comment")
+ } else { string.into_maybe_owned() };
+ token::DOC_COMMENT(token::intern(string.as_slice()))
} else {
- let last_bpos = self.last_pos;
- self.err_span_(start_bpos, last_bpos, "scan_exponent: bad fp literal");
- rslt.push_str("1"); // arbitrary placeholder exponent
- return Some(rslt);
- }
- } else {
- return None::<String>;
- }
+ token::COMMENT
+ };
+
+ Some(TokenAndSpan{
+ tok: tok,
+ sp: codemap::mk_sp(start_bpos, self.last_pos)
+ })
+ })
}
- fn scan_digits(&mut self, radix: uint) -> String {
- let mut rslt = String::new();
+ /// Scan through any digits (base `radix`) or underscores, and return how
+ /// many digits there were.
+ fn scan_digits(&mut self, radix: uint) -> uint {
+ let mut len = 0u;
loop {
let c = self.curr;
- if c == Some('_') { self.bump(); continue; }
+ if c == Some('_') { debug!("skipping a _"); self.bump(); continue; }
match c.and_then(|cc| char::to_digit(cc, radix)) {
- Some(_) => {
- rslt.push_char(c.unwrap());
- self.bump();
- }
- _ => return rslt
+ Some(_) => {
+ debug!("{} in scan_digits", c);
+ len += 1;
+ self.bump();
+ }
+ _ => return len
}
};
}
- fn check_float_base(&mut self, start_bpos: BytePos, last_bpos: BytePos, base: uint) {
- match base {
- 16u => self.err_span_(start_bpos, last_bpos,
- "hexadecimal float literal is not supported"),
- 8u => self.err_span_(start_bpos, last_bpos, "octal float literal is not supported"),
- 2u => self.err_span_(start_bpos, last_bpos, "binary float literal is not supported"),
- _ => ()
- }
- }
-
+ /// Lex a LIT_INTEGER or a LIT_FLOAT
fn scan_number(&mut self, c: char) -> token::Token {
- let mut num_str;
- let mut base = 10u;
- let mut c = c;
- let mut n = self.nextch().unwrap_or('\x00');
+ let mut num_digits;
+ let mut base = 10;
let start_bpos = self.last_pos;
- if c == '0' && n == 'x' {
- self.bump();
- self.bump();
- base = 16u;
- } else if c == '0' && n == 'o' {
- self.bump();
- self.bump();
- base = 8u;
- } else if c == '0' && n == 'b' {
- self.bump();
- self.bump();
- base = 2u;
- }
- num_str = self.scan_digits(base);
- c = self.curr.unwrap_or('\x00');
- self.nextch();
- if c == 'u' || c == 'i' {
- enum Result { Signed(ast::IntTy), Unsigned(ast::UintTy) }
- let signed = c == 'i';
- let mut tp = {
- if signed { Signed(ast::TyI) }
- else { Unsigned(ast::TyU) }
- };
- self.bump();
- c = self.curr.unwrap_or('\x00');
- if c == '8' {
- self.bump();
- tp = if signed { Signed(ast::TyI8) }
- else { Unsigned(ast::TyU8) };
- }
- n = self.nextch().unwrap_or('\x00');
- if c == '1' && n == '6' {
- self.bump();
- self.bump();
- tp = if signed { Signed(ast::TyI16) }
- else { Unsigned(ast::TyU16) };
- } else if c == '3' && n == '2' {
- self.bump();
- self.bump();
- tp = if signed { Signed(ast::TyI32) }
- else { Unsigned(ast::TyU32) };
- } else if c == '6' && n == '4' {
- self.bump();
- self.bump();
- tp = if signed { Signed(ast::TyI64) }
- else { Unsigned(ast::TyU64) };
- }
- if num_str.len() == 0u {
- let last_bpos = self.last_pos;
- self.err_span_(start_bpos, last_bpos, "no valid digits found for number");
- num_str = "1".to_string();
- }
- let parsed = match from_str_radix::<u64>(num_str.as_slice(),
- base as uint) {
- Some(p) => p,
- None => {
- let last_bpos = self.last_pos;
- self.err_span_(start_bpos, last_bpos, "int literal is too large");
- 1
- }
- };
- match tp {
- Signed(t) => return token::LIT_INT(parsed as i64, t),
- Unsigned(t) => return token::LIT_UINT(parsed, t)
+ self.bump();
+
+ if c == '0' {
+ match self.curr.unwrap_or('\0') {
+ 'b' => { self.bump(); base = 2; num_digits = self.scan_digits(2); }
+ 'o' => { self.bump(); base = 8; num_digits = self.scan_digits(8); }
+ 'x' => { self.bump(); base = 16; num_digits = self.scan_digits(16); }
+ '0'..'9' | '_' | '.' => {
+ num_digits = self.scan_digits(10) + 1;
+ }
+ 'u' | 'i' => {
+ self.scan_int_suffix();
+ return token::LIT_INTEGER(self.name_from(start_bpos));
+ },
+ 'f' => {
+ let last_pos = self.last_pos;
+ self.scan_float_suffix();
+ self.check_float_base(start_bpos, last_pos, base);
+ return token::LIT_FLOAT(self.name_from(start_bpos));
+ }
+ _ => {
+ // just a 0
+ return token::LIT_INTEGER(self.name_from(start_bpos));
+ }
}
+ } else if c.is_digit_radix(10) {
+ num_digits = self.scan_digits(10) + 1;
+ } else {
+ num_digits = 0;
}
- let mut is_float = false;
- if self.curr_is('.') && !(ident_start(self.nextch()) || self.nextch_is('.')) {
- is_float = true;
- self.bump();
- let dec_part = self.scan_digits(10u);
- num_str.push_char('.');
- num_str.push_str(dec_part.as_slice());
- }
- match self.scan_exponent(start_bpos) {
- Some(ref s) => {
- is_float = true;
- num_str.push_str(s.as_slice());
- }
- None => ()
+
+ if num_digits == 0 {
+ self.err_span_(start_bpos, self.last_pos, "no valid digits found for number");
+ // eat any suffix
+ self.scan_int_suffix();
+ return token::LIT_INTEGER(token::intern("0"));
}
- if self.curr_is('f') {
+ // might be a float, but don't be greedy if this is actually an
+ // integer literal followed by field/method access or a range pattern
+ // (`0..2` and `12.foo()`)
+ if self.curr_is('.') && !self.nextch_is('.') && !self.nextch().unwrap_or('\0')
+ .is_XID_start() {
+ // might have stuff after the ., and if it does, it needs to start
+ // with a number
self.bump();
- c = self.curr.unwrap_or('\x00');
- n = self.nextch().unwrap_or('\x00');
- if c == '3' && n == '2' {
- self.bump();
- self.bump();
- let last_bpos = self.last_pos;
- self.check_float_base(start_bpos, last_bpos, base);
- return token::LIT_FLOAT(str_to_ident(num_str.as_slice()),
- ast::TyF32);
- } else if c == '6' && n == '4' {
- self.bump();
- self.bump();
- let last_bpos = self.last_pos;
- self.check_float_base(start_bpos, last_bpos, base);
- return token::LIT_FLOAT(str_to_ident(num_str.as_slice()),
- ast::TyF64);
- /* FIXME (#2252): if this is out of range for either a
- 32-bit or 64-bit float, it won't be noticed till the
- back-end. */
+ if self.curr.unwrap_or('\0').is_digit_radix(10) {
+ self.scan_digits(10);
+ self.scan_float_exponent();
+ self.scan_float_suffix();
}
- let last_bpos = self.last_pos;
- self.err_span_(start_bpos, last_bpos, "expected `f32` or `f64` suffix");
- }
- if is_float {
- let last_bpos = self.last_pos;
- self.check_float_base(start_bpos, last_bpos, base);
- return token::LIT_FLOAT_UNSUFFIXED(str_to_ident(
- num_str.as_slice()));
+ let last_pos = self.last_pos;
+ self.check_float_base(start_bpos, last_pos, base);
+ return token::LIT_FLOAT(self.name_from(start_bpos));
+ } else if self.curr_is('f') {
+ // or it might be an integer literal suffixed as a float
+ self.scan_float_suffix();
+ let last_pos = self.last_pos;
+ self.check_float_base(start_bpos, last_pos, base);
+ return token::LIT_FLOAT(self.name_from(start_bpos));
} else {
- if num_str.len() == 0u {
- let last_bpos = self.last_pos;
- self.err_span_(start_bpos, last_bpos, "no valid digits found for number");
- num_str = "1".to_string();
+ // it might be a float if it has an exponent
+ if self.curr_is('e') || self.curr_is('E') {
+ self.scan_float_exponent();
+ self.scan_float_suffix();
+ let last_pos = self.last_pos;
+ self.check_float_base(start_bpos, last_pos, base);
+ return token::LIT_FLOAT(self.name_from(start_bpos));
}
- let parsed = match from_str_radix::<u64>(num_str.as_slice(),
- base as uint) {
- Some(p) => p,
- None => {
- let last_bpos = self.last_pos;
- self.err_span_(start_bpos, last_bpos, "int literal is too large");
- 1
- }
- };
-
- debug!("lexing {} as an unsuffixed integer literal",
- num_str.as_slice());
- return token::LIT_INT_UNSUFFIXED(parsed as i64);
+ // but we certainly have an integer!
+ self.scan_int_suffix();
+ return token::LIT_INTEGER(self.name_from(start_bpos));
}
}
-
- fn scan_numeric_escape(&mut self, n_hex_digits: uint, delim: char) -> char {
- let mut accum_int = 0u32;
+ /// Scan over `n_digits` hex digits, stopping at `delim`, reporting an
+ /// error if too many or too few digits are encountered.
+ fn scan_hex_digits(&mut self, n_digits: uint, delim: char) -> bool {
+ debug!("scanning {} digits until {}", n_digits, delim);
let start_bpos = self.last_pos;
- for _ in range(0, n_hex_digits) {
+ let mut accum_int = 0;
+
+ for _ in range(0, n_digits) {
if self.is_eof() {
let last_bpos = self.last_pos;
self.fatal_span_(start_bpos, last_bpos, "unterminated numeric character escape");
}
match char::from_u32(accum_int) {
- Some(x) => x,
+ Some(_) => true,
None => {
let last_bpos = self.last_pos;
self.err_span_(start_bpos, last_bpos, "illegal numeric character escape");
- '?'
+ false
}
}
}
/// Scan for a single (possibly escaped) byte or char
/// in a byte, (non-raw) byte string, char, or (non-raw) string literal.
/// `start` is the position of `first_source_char`, which is already consumed.
+ ///
+ /// Returns true if there was a valid char/byte, false otherwise.
fn scan_char_or_byte(&mut self, start: BytePos, first_source_char: char,
- ascii_only: bool, delim: char) -> Option<char> {
+ ascii_only: bool, delim: char) -> bool {
match first_source_char {
'\\' => {
// '\X' for some X must be a character constant:
match escaped {
None => {}, // EOF here is an error that will be checked later.
Some(e) => {
- return Some(match e {
- 'n' => '\n',
- 'r' => '\r',
- 't' => '\t',
- '\\' => '\\',
- '\'' => '\'',
- '"' => '"',
- '0' => '\x00',
- 'x' => self.scan_numeric_escape(2u, delim),
- 'u' if !ascii_only => self.scan_numeric_escape(4u, delim),
- 'U' if !ascii_only => self.scan_numeric_escape(8u, delim),
+ return match e {
+ 'n' | 'r' | 't' | '\\' | '\'' | '"' | '0' => true,
+ 'x' => self.scan_hex_digits(2u, delim),
+ 'u' if !ascii_only => self.scan_hex_digits(4u, delim),
+ 'U' if !ascii_only => self.scan_hex_digits(8u, delim),
'\n' if delim == '"' => {
self.consume_whitespace();
- return None
+ true
},
'\r' if delim == '"' && self.curr_is('\n') => {
self.consume_whitespace();
- return None
+ true
}
c => {
let last_pos = self.last_pos;
if ascii_only { "unknown byte escape" }
else { "unknown character escape" },
c);
- c
+ false
}
- })
+ }
}
}
}
if ascii_only { "byte constant must be escaped" }
else { "character constant must be escaped" },
first_source_char);
+ return false;
}
'\r' => {
if self.curr_is('\n') {
self.bump();
- return Some('\n');
+ return true;
} else {
self.err_span_(start, self.last_pos,
"bare CR not allowed in string, use \\r instead");
+ return false;
}
}
_ => if ascii_only && first_source_char > '\x7F' {
start, last_pos,
"byte constant must be ASCII. \
Use a \\xHH escape for a non-ASCII byte", first_source_char);
+ return false;
+ }
+ }
+ true
+ }
+
+ /// Scan over an int literal suffix.
+ fn scan_int_suffix(&mut self) {
+ match self.curr {
+ Some('i') | Some('u') => {
+ self.bump();
+
+ if self.curr_is('8') {
+ self.bump();
+ } else if self.curr_is('1') {
+ if !self.nextch_is('6') {
+ self.err_span_(self.last_pos, self.pos,
+ "illegal int suffix");
+ } else {
+ self.bump(); self.bump();
+ }
+ } else if self.curr_is('3') {
+ if !self.nextch_is('2') {
+ self.err_span_(self.last_pos, self.pos,
+ "illegal int suffix");
+ } else {
+ self.bump(); self.bump();
+ }
+ } else if self.curr_is('6') {
+ if !self.nextch_is('4') {
+ self.err_span_(self.last_pos, self.pos,
+ "illegal int suffix");
+ } else {
+ self.bump(); self.bump();
+ }
+ }
+ },
+ _ => { }
+ }
+ }
+
+ /// Scan over a float literal suffix
+ fn scan_float_suffix(&mut self) {
+ if self.curr_is('f') {
+ if (self.nextch_is('3') && self.nextnextch_is('2'))
+ || (self.nextch_is('6') && self.nextnextch_is('4')) {
+ self.bump();
+ self.bump();
+ self.bump();
+ } else {
+ self.err_span_(self.last_pos, self.pos, "illegal float suffix");
}
}
- Some(first_source_char)
+ }
+
+ /// Scan over a float exponent.
+ fn scan_float_exponent(&mut self) {
+ if self.curr_is('e') || self.curr_is('E') {
+ self.bump();
+ if self.curr_is('-') || self.curr_is('+') {
+ self.bump();
+ }
+ if self.scan_digits(10) == 0 {
+ self.err_span_(self.last_pos, self.pos, "expected at least one digit in exponent")
+ }
+ }
+ }
+
+ /// Check that a base is valid for a floating literal, emitting a nice
+ /// error if it isn't.
+ fn check_float_base(&mut self, start_bpos: BytePos, last_bpos: BytePos, base: uint) {
+ match base {
+ 16u => self.err_span_(start_bpos, last_bpos, "hexadecimal float literal is not \
+ supported"),
+ 8u => self.err_span_(start_bpos, last_bpos, "octal float literal is not supported"),
+ 2u => self.err_span_(start_bpos, last_bpos, "binary float literal is not supported"),
+ _ => ()
+ }
}
fn binop(&mut self, op: token::BinOp) -> token::Token {
'@' => { self.bump(); return token::AT; }
'#' => { self.bump(); return token::POUND; }
'~' => { self.bump(); return token::TILDE; }
+ '?' => { self.bump(); return token::QUESTION; }
':' => {
self.bump();
if self.curr_is(':') {
let start = self.last_pos;
// the eof will be picked up by the final `'` check below
- let mut c2 = self.curr.unwrap_or('\x00');
+ let c2 = self.curr.unwrap_or('\x00');
self.bump();
// If the character is an ident start not followed by another single
}
// Otherwise it is a character constant:
- c2 = self.scan_char_or_byte(start, c2, /* ascii_only = */ false, '\'').unwrap();
+ let valid = self.scan_char_or_byte(start, c2, /* ascii_only = */ false, '\'');
if !self.curr_is('\'') {
let last_bpos = self.last_pos;
self.fatal_span_verbose(
start - BytePos(1), last_bpos,
"unterminated character constant".to_string());
}
+ let id = if valid { self.name_from(start) } else { token::intern("0") };
self.bump(); // advance curr past token
- return token::LIT_CHAR(c2);
+ return token::LIT_CHAR(id);
}
'b' => {
self.bump();
return match self.curr {
- Some('\'') => parse_byte(self),
- Some('"') => parse_byte_string(self),
- Some('r') => parse_raw_byte_string(self),
+ Some('\'') => self.scan_byte(),
+ Some('"') => self.scan_byte_string(),
+ Some('r') => self.scan_raw_byte_string(),
_ => unreachable!() // Should have been a token::IDENT above.
};
- fn parse_byte(self_: &mut StringReader) -> token::Token {
- self_.bump();
- let start = self_.last_pos;
-
- // the eof will be picked up by the final `'` check below
- let mut c2 = self_.curr.unwrap_or('\x00');
- self_.bump();
-
- c2 = self_.scan_char_or_byte(start, c2, /* ascii_only = */ true, '\'').unwrap();
- if !self_.curr_is('\'') {
- // Byte offsetting here is okay because the
- // character before position `start` are an
- // ascii single quote and ascii 'b'.
- let last_pos = self_.last_pos;
- self_.fatal_span_verbose(
- start - BytePos(2), last_pos,
- "unterminated byte constant".to_string());
- }
- self_.bump(); // advance curr past token
- return token::LIT_BYTE(c2 as u8);
- }
-
- fn parse_byte_string(self_: &mut StringReader) -> token::Token {
- self_.bump();
- let start = self_.last_pos;
- let mut value = Vec::new();
- while !self_.curr_is('"') {
- if self_.is_eof() {
- let last_pos = self_.last_pos;
- self_.fatal_span_(start, last_pos,
- "unterminated double quote byte string");
- }
-
- let ch_start = self_.last_pos;
- let ch = self_.curr.unwrap();
- self_.bump();
- self_.scan_char_or_byte(ch_start, ch, /* ascii_only = */ true, '"')
- .map(|ch| value.push(ch as u8));
- }
- self_.bump();
- return token::LIT_BINARY(Rc::new(value));
- }
-
- fn parse_raw_byte_string(self_: &mut StringReader) -> token::Token {
- let start_bpos = self_.last_pos;
- self_.bump();
- let mut hash_count = 0u;
- while self_.curr_is('#') {
- self_.bump();
- hash_count += 1;
- }
-
- if self_.is_eof() {
- let last_pos = self_.last_pos;
- self_.fatal_span_(start_bpos, last_pos, "unterminated raw string");
- } else if !self_.curr_is('"') {
- let last_pos = self_.last_pos;
- let ch = self_.curr.unwrap();
- self_.fatal_span_char(start_bpos, last_pos,
- "only `#` is allowed in raw string delimitation; \
- found illegal character",
- ch);
- }
- self_.bump();
- let content_start_bpos = self_.last_pos;
- let mut content_end_bpos;
- 'outer: loop {
- match self_.curr {
- None => {
- let last_pos = self_.last_pos;
- self_.fatal_span_(start_bpos, last_pos, "unterminated raw string")
- },
- Some('"') => {
- content_end_bpos = self_.last_pos;
- for _ in range(0, hash_count) {
- self_.bump();
- if !self_.curr_is('#') {
- continue 'outer;
- }
- }
- break;
- },
- Some(c) => if c > '\x7F' {
- let last_pos = self_.last_pos;
- self_.err_span_char(
- last_pos, last_pos, "raw byte string must be ASCII", c);
- }
- }
- self_.bump();
- }
- self_.bump();
- let bytes = self_.with_str_from_to(content_start_bpos,
- content_end_bpos,
- |s| s.as_bytes().to_owned());
- return token::LIT_BINARY_RAW(Rc::new(bytes), hash_count);
- }
}
'"' => {
- let mut accum_str = String::new();
let start_bpos = self.last_pos;
+ let mut valid = true;
self.bump();
while !self.curr_is('"') {
if self.is_eof() {
let ch_start = self.last_pos;
let ch = self.curr.unwrap();
self.bump();
- self.scan_char_or_byte(ch_start, ch, /* ascii_only = */ false, '"')
- .map(|ch| accum_str.push_char(ch));
+ valid &= self.scan_char_or_byte(ch_start, ch, /* ascii_only = */ false, '"');
}
+ // adjust for the ACSII " at the start of the literal
+ let id = if valid { self.name_from(start_bpos + BytePos(1)) }
+ else { token::intern("??") };
self.bump();
- return token::LIT_STR(str_to_ident(accum_str.as_slice()));
+ return token::LIT_STR(id);
}
'r' => {
let start_bpos = self.last_pos;
self.bump();
let content_start_bpos = self.last_pos;
let mut content_end_bpos;
- let mut has_cr = false;
+ let mut valid = true;
'outer: loop {
if self.is_eof() {
let last_bpos = self.last_pos;
}
}
break;
- }
+ },
'\r' => {
- has_cr = true;
+ if !self.nextch_is('\n') {
+ let last_bpos = self.last_pos;
+ self.err_span_(start_bpos, last_bpos, "bare CR not allowed in raw \
+ string, use \\r instead");
+ valid = false;
+ }
}
_ => ()
}
self.bump();
}
self.bump();
- let str_content = self.with_str_from_to(content_start_bpos, content_end_bpos, |string| {
- let string = if has_cr {
- self.translate_crlf(content_start_bpos, string,
- "bare CR not allowed in raw string")
- } else { string.into_maybe_owned() };
- str_to_ident(string.as_slice())
- });
- return token::LIT_STR_RAW(str_content, hash_count);
+ let id = if valid {
+ self.name_from_to(content_start_bpos, content_end_bpos)
+ } else {
+ token::intern("??")
+ };
+ return token::LIT_STR_RAW(id, hash_count);
}
'-' => {
if self.nextch_is('>') {
// consider shebangs comments, but not inner attributes
|| (self.curr_is('#') && self.nextch_is('!') && !self.nextnextch_is('['))
}
+
+ fn scan_byte(&mut self) -> token::Token {
+ self.bump();
+ let start = self.last_pos;
+
+ // the eof will be picked up by the final `'` check below
+ let c2 = self.curr.unwrap_or('\x00');
+ self.bump();
+
+ let valid = self.scan_char_or_byte(start, c2, /* ascii_only = */ true, '\'');
+ if !self.curr_is('\'') {
+ // Byte offsetting here is okay because the
+ // character before position `start` are an
+ // ascii single quote and ascii 'b'.
+ let last_pos = self.last_pos;
+ self.fatal_span_verbose(
+ start - BytePos(2), last_pos,
+ "unterminated byte constant".to_string());
+ }
+
+ let id = if valid { self.name_from(start) } else { token::intern("??") };
+ self.bump(); // advance curr past token
+ return token::LIT_BYTE(id);
+ }
+
+ fn scan_byte_string(&mut self) -> token::Token {
+ self.bump();
+ let start = self.last_pos;
+ let mut valid = true;
+
+ while !self.curr_is('"') {
+ if self.is_eof() {
+ let last_pos = self.last_pos;
+ self.fatal_span_(start, last_pos,
+ "unterminated double quote byte string");
+ }
+
+ let ch_start = self.last_pos;
+ let ch = self.curr.unwrap();
+ self.bump();
+ valid &= self.scan_char_or_byte(ch_start, ch, /* ascii_only = */ true, '"');
+ }
+ let id = if valid { self.name_from(start) } else { token::intern("??") };
+ self.bump();
+ return token::LIT_BINARY(id);
+ }
+
+ fn scan_raw_byte_string(&mut self) -> token::Token {
+ let start_bpos = self.last_pos;
+ self.bump();
+ let mut hash_count = 0u;
+ while self.curr_is('#') {
+ self.bump();
+ hash_count += 1;
+ }
+
+ if self.is_eof() {
+ let last_pos = self.last_pos;
+ self.fatal_span_(start_bpos, last_pos, "unterminated raw string");
+ } else if !self.curr_is('"') {
+ let last_pos = self.last_pos;
+ let ch = self.curr.unwrap();
+ self.fatal_span_char(start_bpos, last_pos,
+ "only `#` is allowed in raw string delimitation; \
+ found illegal character",
+ ch);
+ }
+ self.bump();
+ let content_start_bpos = self.last_pos;
+ let mut content_end_bpos;
+ 'outer: loop {
+ match self.curr {
+ None => {
+ let last_pos = self.last_pos;
+ self.fatal_span_(start_bpos, last_pos, "unterminated raw string")
+ },
+ Some('"') => {
+ content_end_bpos = self.last_pos;
+ for _ in range(0, hash_count) {
+ self.bump();
+ if !self.curr_is('#') {
+ continue 'outer;
+ }
+ }
+ break;
+ },
+ Some(c) => if c > '\x7F' {
+ let last_pos = self.last_pos;
+ self.err_span_char(
+ last_pos, last_pos, "raw byte string must be ASCII", c);
+ }
+ }
+ self.bump();
+ }
+ self.bump();
+ return token::LIT_BINARY_RAW(self.name_from_to(content_start_bpos, content_end_bpos),
+ hash_count);
+ }
}
pub fn is_whitespace(c: Option<char>) -> bool {
fn is_dec_digit(c: Option<char>) -> bool { return in_range(c, '0', '9'); }
-pub fn is_line_non_doc_comment(s: &str) -> bool {
- s.starts_with("////")
+pub fn is_doc_comment(s: &str) -> bool {
+ let res = (s.starts_with("///") && *s.as_bytes().get(3).unwrap_or(&b' ') != b'/')
+ || s.starts_with("//!");
+ debug!("is `{}` a doc comment? {}", s, res);
+ res
}
-pub fn is_block_non_doc_comment(s: &str) -> bool {
- s.starts_with("/***")
+pub fn is_block_doc_comment(s: &str) -> bool {
+ let res = (s.starts_with("/**") && *s.as_bytes().get(3).unwrap_or(&b' ') != b'*')
+ || s.starts_with("/*!");
+ debug!("is `{}` a doc comment? {}", s, res);
+ res
}
fn ident_start(c: Option<char>) -> bool {
use std::io::util;
fn mk_sh() -> diagnostic::SpanHandler {
- let emitter = diagnostic::EmitterWriter::new(box util::NullWriter);
+ let emitter = diagnostic::EmitterWriter::new(box util::NullWriter, None);
let handler = diagnostic::mk_handler(box emitter);
diagnostic::mk_span_handler(handler, CodeMap::new())
}
"/* my source file */ \
fn main() { println!(\"zebra\"); }\n".to_string());
let id = str_to_ident("fn");
+ assert_eq!(string_reader.next_token().tok, token::COMMENT);
+ assert_eq!(string_reader.next_token().tok, token::WS);
let tok1 = string_reader.next_token();
let tok2 = TokenAndSpan{
tok:token::IDENT(id, false),
sp:Span {lo:BytePos(21),hi:BytePos(23),expn_info: None}};
assert_eq!(tok1,tok2);
+ assert_eq!(string_reader.next_token().tok, token::WS);
// the 'main' id is already read:
assert_eq!(string_reader.last_pos.clone(), BytePos(28));
// read another token:
#[test] fn doublecolonparsing () {
check_tokenization(setup(&mk_sh(), "a b".to_string()),
vec!(mk_ident("a",false),
+ token::WS,
mk_ident("b",false)));
}
#[test] fn dcparsing_3 () {
check_tokenization(setup(&mk_sh(), "a ::b".to_string()),
vec!(mk_ident("a",false),
+ token::WS,
token::MOD_SEP,
mk_ident("b",false)));
}
check_tokenization(setup(&mk_sh(), "a:: b".to_string()),
vec!(mk_ident("a",true),
token::MOD_SEP,
+ token::WS,
mk_ident("b",false)));
}
#[test] fn character_a() {
assert_eq!(setup(&mk_sh(), "'a'".to_string()).next_token().tok,
- token::LIT_CHAR('a'));
+ token::LIT_CHAR(token::intern("a")));
}
#[test] fn character_space() {
assert_eq!(setup(&mk_sh(), "' '".to_string()).next_token().tok,
- token::LIT_CHAR(' '));
+ token::LIT_CHAR(token::intern(" ")));
}
#[test] fn character_escaped() {
assert_eq!(setup(&mk_sh(), "'\\n'".to_string()).next_token().tok,
- token::LIT_CHAR('\n'));
+ token::LIT_CHAR(token::intern("\\n")));
}
#[test] fn lifetime_name() {
assert_eq!(setup(&mk_sh(),
"r###\"\"#a\\b\x00c\"\"###".to_string()).next_token()
.tok,
- token::LIT_STR_RAW(token::str_to_ident("\"#a\\b\x00c\""), 3));
+ token::LIT_STR_RAW(token::intern("\"#a\\b\x00c\""), 3));
}
#[test] fn line_doc_comments() {
- assert!(!is_line_non_doc_comment("///"));
- assert!(!is_line_non_doc_comment("/// blah"));
- assert!(is_line_non_doc_comment("////"));
+ assert!(is_doc_comment("///"));
+ assert!(is_doc_comment("/// blah"));
+ assert!(!is_doc_comment("////"));
}
#[test] fn nested_block_comments() {
- assert_eq!(setup(&mk_sh(),
- "/* /* */ */'a'".to_string()).next_token().tok,
- token::LIT_CHAR('a'));
+ let sh = mk_sh();
+ let mut lexer = setup(&sh, "/* /* */ */'a'".to_string());
+ match lexer.next_token().tok {
+ token::COMMENT => { },
+ _ => fail!("expected a comment!")
+ }
+ assert_eq!(lexer.next_token().tok, token::LIT_CHAR(token::intern("a")));
}
}
//! The main parser interface
-
use ast;
use codemap::{Span, CodeMap, FileMap};
use diagnostic::{SpanHandler, mk_span_handler, default_handler, Auto};
pub mod classify;
pub mod obsolete;
-// info about a parsing session.
+/// Info about a parsing session.
pub struct ParseSess {
pub span_diagnostic: SpanHandler, // better be the same as the one in the reader!
/// Used to determine and report recursive mod inclusions
pub fn new_parse_sess() -> ParseSess {
ParseSess {
- span_diagnostic: mk_span_handler(default_handler(Auto), CodeMap::new()),
+ span_diagnostic: mk_span_handler(default_handler(Auto, None), CodeMap::new()),
included_mod_stack: RefCell::new(Vec::new()),
}
}
unreachable!()
}
-// given a session and a string, add the string to
-// the session's codemap and return the new filemap
+/// Given a session and a string, add the string to
+/// the session's codemap and return the new filemap
pub fn string_to_filemap(sess: &ParseSess, source: String, path: String)
-> Rc<FileMap> {
sess.span_diagnostic.cm.new_filemap(path, source)
}
-// given a filemap, produce a sequence of token-trees
+/// Given a filemap, produce a sequence of token-trees
pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc<FileMap>)
-> Vec<ast::TokenTree> {
// it appears to me that the cfg doesn't matter here... indeed,
p1.parse_all_token_trees()
}
-// given tts and cfg, produce a parser
+/// Given tts and cfg, produce a parser
pub fn tts_to_parser<'a>(sess: &'a ParseSess,
tts: Vec<ast::TokenTree>,
cfg: ast::CrateConfig) -> Parser<'a> {
Parser::new(sess, cfg, box trdr)
}
-// abort if necessary
+/// Abort if necessary
pub fn maybe_aborted<T>(result: T, mut p: Parser) -> T {
p.abort_if_errors();
result
}
+/// Parse a string representing a character literal into its final form.
+/// Rather than just accepting/rejecting a given literal, unescapes it as
+/// well. Can take any slice prefixed by a character escape. Returns the
+/// character and the number of characters consumed.
+pub fn char_lit(lit: &str) -> (char, int) {
+ use std::{num, char};
+
+ let mut chars = lit.chars();
+ let c = match (chars.next(), chars.next()) {
+ (Some(c), None) if c != '\\' => return (c, 1),
+ (Some('\\'), Some(c)) => match c {
+ '"' => Some('"'),
+ 'n' => Some('\n'),
+ 'r' => Some('\r'),
+ 't' => Some('\t'),
+ '\\' => Some('\\'),
+ '\'' => Some('\''),
+ '0' => Some('\0'),
+ _ => { None }
+ },
+ _ => fail!("lexer accepted invalid char escape `{}`", lit)
+ };
+
+ match c {
+ Some(x) => return (x, 2),
+ None => { }
+ }
+
+ let msg = format!("lexer should have rejected a bad character escape {}", lit);
+ let msg2 = msg.as_slice();
+
+ let esc: |uint| -> Option<(char, int)> = |len|
+ num::from_str_radix(lit.slice(2, len), 16)
+ .and_then(char::from_u32)
+ .map(|x| (x, len as int));
+
+ // Unicode escapes
+ return match lit.as_bytes()[1] as char {
+ 'x' | 'X' => esc(4),
+ 'u' => esc(6),
+ 'U' => esc(10),
+ _ => None,
+ }.expect(msg2);
+}
+
+/// Parse a string representing a string literal into its final form. Does
+/// unescaping.
+pub fn str_lit(lit: &str) -> String {
+ debug!("parse_str_lit: given {}", lit.escape_default());
+ let mut res = String::with_capacity(lit.len());
+
+ // FIXME #8372: This could be a for-loop if it didn't borrow the iterator
+ let error = |i| format!("lexer should have rejected {} at {}", lit, i);
+
+ /// Eat everything up to a non-whitespace
+ fn eat<'a>(it: &mut ::std::iter::Peekable<(uint, char), ::std::str::CharOffsets<'a>>) {
+ loop {
+ match it.peek().map(|x| x.val1()) {
+ Some(' ') | Some('\n') | Some('\r') | Some('\t') => {
+ it.next();
+ },
+ _ => { break; }
+ }
+ }
+ }
+
+ let mut chars = lit.char_indices().peekable();
+ loop {
+ match chars.next() {
+ Some((i, c)) => {
+ let em = error(i);
+ match c {
+ '\\' => {
+ if chars.peek().expect(em.as_slice()).val1() == '\n' {
+ eat(&mut chars);
+ } else if chars.peek().expect(em.as_slice()).val1() == '\r' {
+ chars.next();
+ if chars.peek().expect(em.as_slice()).val1() != '\n' {
+ fail!("lexer accepted bare CR");
+ }
+ eat(&mut chars);
+ } else {
+ // otherwise, a normal escape
+ let (c, n) = char_lit(lit.slice_from(i));
+ for _ in range(0, n - 1) { // we don't need to move past the first \
+ chars.next();
+ }
+ res.push_char(c);
+ }
+ },
+ '\r' => {
+ if chars.peek().expect(em.as_slice()).val1() != '\n' {
+ fail!("lexer accepted bare CR");
+ }
+ chars.next();
+ res.push_char('\n');
+ }
+ c => res.push_char(c),
+ }
+ },
+ None => break
+ }
+ }
+
+ res.shrink_to_fit(); // probably not going to do anything, unless there was an escape.
+ debug!("parse_str_lit: returning {}", res);
+ res
+}
+
+/// Parse a string representing a raw string literal into its final form. The
+/// only operation this does is convert embedded CRLF into a single LF.
+pub fn raw_str_lit(lit: &str) -> String {
+ debug!("raw_str_lit: given {}", lit.escape_default());
+ let mut res = String::with_capacity(lit.len());
+
+ // FIXME #8372: This could be a for-loop if it didn't borrow the iterator
+ let mut chars = lit.chars().peekable();
+ loop {
+ match chars.next() {
+ Some(c) => {
+ if c == '\r' {
+ if *chars.peek().unwrap() != '\n' {
+ fail!("lexer accepted bare CR");
+ }
+ chars.next();
+ res.push_char('\n');
+ } else {
+ res.push_char(c);
+ }
+ },
+ None => break
+ }
+ }
+
+ res.shrink_to_fit();
+ res
+}
+
+pub fn float_lit(s: &str) -> ast::Lit_ {
+ debug!("float_lit: {}", s);
+ // FIXME #2252: bounds checking float literals is defered until trans
+ let s2 = s.chars().filter(|&c| c != '_').collect::<String>();
+ let s = s2.as_slice();
+
+ let mut ty = None;
+
+ if s.ends_with("f32") {
+ ty = Some(ast::TyF32);
+ } else if s.ends_with("f64") {
+ ty = Some(ast::TyF64);
+ }
+
+
+ match ty {
+ Some(t) => {
+ ast::LitFloat(token::intern_and_get_ident(s.slice_to(s.len() - t.suffix_len())), t)
+ },
+ None => ast::LitFloatUnsuffixed(token::intern_and_get_ident(s))
+ }
+}
+
+/// Parse a string representing a byte literal into its final form. Similar to `char_lit`
+pub fn byte_lit(lit: &str) -> (u8, uint) {
+ let err = |i| format!("lexer accepted invalid byte literal {} step {}", lit, i);
+
+ if lit.len() == 1 {
+ (lit.as_bytes()[0], 1)
+ } else {
+ assert!(lit.as_bytes()[0] == b'\\', err(0i));
+ let b = match lit.as_bytes()[1] {
+ b'"' => b'"',
+ b'n' => b'\n',
+ b'r' => b'\r',
+ b't' => b'\t',
+ b'\\' => b'\\',
+ b'\'' => b'\'',
+ b'0' => b'\0',
+ _ => {
+ match ::std::num::from_str_radix::<u64>(lit.slice(2, 4), 16) {
+ Some(c) =>
+ if c > 0xFF {
+ fail!(err(2))
+ } else {
+ return (c as u8, 4)
+ },
+ None => fail!(err(3))
+ }
+ }
+ };
+ return (b, 2);
+ }
+}
+
+pub fn binary_lit(lit: &str) -> Rc<Vec<u8>> {
+ let mut res = Vec::with_capacity(lit.len());
+ // FIXME #8372: This could be a for-loop if it didn't borrow the iterator
+ let error = |i| format!("lexer should have rejected {} at {}", lit, i);
+
+ // binary literals *must* be ASCII, but the escapes don't have to be
+ let mut chars = lit.as_bytes().iter().enumerate().peekable();
+ loop {
+ match chars.next() {
+ Some((i, &c)) => {
+ if c == b'\\' {
+ if *chars.peek().expect(error(i).as_slice()).val1() == b'\n' {
+ loop {
+ // eat everything up to a non-whitespace
+ match chars.peek().map(|x| *x.val1()) {
+ Some(b' ') | Some(b'\n') | Some(b'\r') | Some(b'\t') => {
+ chars.next();
+ },
+ _ => { break; }
+ }
+ }
+ } else {
+ // otherwise, a normal escape
+ let (c, n) = byte_lit(lit.slice_from(i));
+ for _ in range(0, n - 1) { // we don't need to move past the first \
+ chars.next();
+ }
+ res.push(c);
+ }
+ } else {
+ res.push(c);
+ }
+ },
+ None => { break; }
+ }
+ }
+
+ Rc::new(res)
+}
+
+pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
+ // s can only be ascii, byte indexing is fine
+
+ let s2 = s.chars().filter(|&c| c != '_').collect::<String>();
+ let mut s = s2.as_slice();
+
+ debug!("parse_integer_lit: {}", s);
+
+ if s.len() == 1 {
+ return ast::LitIntUnsuffixed((s.char_at(0)).to_digit(10).unwrap() as i64);
+ }
+
+ let mut base = 10;
+ let orig = s;
+
+ #[deriving(Show)]
+ enum Result {
+ Nothing,
+ Signed(ast::IntTy),
+ Unsigned(ast::UintTy)
+ }
+
+ impl Result {
+ fn suffix_len(&self) -> uint {
+ match *self {
+ Nothing => 0,
+ Signed(s) => s.suffix_len(),
+ Unsigned(u) => u.suffix_len()
+ }
+ }
+ }
+
+ let mut ty = Nothing;
+
+
+ if s.char_at(0) == '0' {
+ match s.char_at(1) {
+ 'x' => base = 16,
+ 'o' => base = 8,
+ 'b' => base = 2,
+ _ => { }
+ }
+ }
+
+ if base != 10 {
+ s = s.slice_from(2);
+ }
+
+ let last = s.len() - 1;
+ match s.char_at(last) {
+ 'i' => ty = Signed(ast::TyI),
+ 'u' => ty = Unsigned(ast::TyU),
+ '8' => {
+ if s.len() > 2 {
+ match s.char_at(last - 1) {
+ 'i' => ty = Signed(ast::TyI8),
+ 'u' => ty = Unsigned(ast::TyU8),
+ _ => { }
+ }
+ }
+ },
+ '6' => {
+ if s.len() > 3 && s.char_at(last - 1) == '1' {
+ match s.char_at(last - 2) {
+ 'i' => ty = Signed(ast::TyI16),
+ 'u' => ty = Unsigned(ast::TyU16),
+ _ => { }
+ }
+ }
+ },
+ '2' => {
+ if s.len() > 3 && s.char_at(last - 1) == '3' {
+ match s.char_at(last - 2) {
+ 'i' => ty = Signed(ast::TyI32),
+ 'u' => ty = Unsigned(ast::TyU32),
+ _ => { }
+ }
+ }
+ },
+ '4' => {
+ if s.len() > 3 && s.char_at(last - 1) == '6' {
+ match s.char_at(last - 2) {
+ 'i' => ty = Signed(ast::TyI64),
+ 'u' => ty = Unsigned(ast::TyU64),
+ _ => { }
+ }
+ }
+ },
+ _ => { }
+ }
+
+
+ s = s.slice_to(s.len() - ty.suffix_len());
+
+ debug!("The suffix is {}, base {}, the new string is {}, the original \
+ string was {}", ty, base, s, orig);
+
+ let res: u64 = match ::std::num::from_str_radix(s, base) {
+ Some(r) => r,
+ None => { sd.span_err(sp, "int literal is too large"); 0 }
+ };
+
+ match ty {
+ Nothing => ast::LitIntUnsuffixed(res as i64),
+ Signed(t) => ast::LitInt(res as i64, t),
+ Unsigned(t) => ast::LitUint(res, t)
+ }
+}
#[cfg(test)]
mod test {
use super::*;
- use serialize::{json, Encodable};
- use std::io;
- use std::io::MemWriter;
- use std::mem::transmute;
- use std::str;
+ use serialize::json;
use std::gc::GC;
use codemap::{Span, BytePos, Spanned};
use owned_slice::OwnedSlice;
use util::parser_testing::{string_to_expr, string_to_item};
use util::parser_testing::string_to_stmt;
- fn to_json_str<'a, E: Encodable<json::Encoder<'a>, io::IoError>>(val: &E) -> String {
- let mut writer = MemWriter::new();
- // FIXME(14302) remove the transmute and unsafe block.
- unsafe {
- let mut encoder = json::Encoder::new(&mut writer as &mut io::Writer);
- let _ = val.encode(transmute(&mut encoder));
- }
- str::from_utf8(writer.unwrap().as_slice()).unwrap().to_string()
- }
-
// produce a codemap::span
fn sp(a: u32, b: u32) -> Span {
Span{lo:BytePos(a),hi:BytePos(b),expn_info:None}
#[test] fn string_to_tts_1 () {
let tts = string_to_tts("fn a (b : int) { b; }".to_string());
- assert_eq!(to_json_str(&tts),
+ assert_eq!(json::encode(&tts),
"[\
{\
\"variant\":\"TTTok\",\
pub trait ParserObsoleteMethods {
/// Reports an obsolete syntax non-fatal error.
fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax);
- // Reports an obsolete syntax non-fatal error, and returns
- // a placeholder expression
+ /// Reports an obsolete syntax non-fatal error, and returns
+ /// a placeholder expression
fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> Gc<Expr>;
fn report(&mut self,
sp: Span,
self.report(sp, kind, kind_str, desc);
}
- // Reports an obsolete syntax non-fatal error, and returns
- // a placeholder expression
+ /// Reports an obsolete syntax non-fatal error, and returns
+ /// a placeholder expression
fn obsolete_expr(&mut self, sp: Span, kind: ObsoleteSyntax) -> Gc<Expr> {
self.obsolete(sp, kind);
self.mk_expr(sp.lo, sp.hi, ExprLit(box(GC) respan(sp, LitNil)))
use ast::{Ident, NormalFn, Inherited, Item, Item_, ItemStatic};
use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl};
use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, Lit, Lit_};
-use ast::{LitBool, LitFloat, LitFloatUnsuffixed, LitInt, LitChar, LitByte, LitBinary};
-use ast::{LitIntUnsuffixed, LitNil, LitStr, LitUint, Local, LocalLet};
+use ast::{LitBool, LitChar, LitByte, LitBinary};
+use ast::{LitNil, LitStr, LitUint, Local, LocalLet};
use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, Matcher, MatchNonterminal};
use ast::{MatchSeq, MatchTok, Method, MutTy, BiMul, Mutability};
use ast::{NamedField, UnNeg, NoReturn, UnNot, P, Pat, PatEnum};
use ast::{PatTup, PatBox, PatWild, PatWildMulti};
use ast::{BiRem, Required};
use ast::{RetStyle, Return, BiShl, BiShr, Stmt, StmtDecl};
-use ast::{Sized, DynSize, StaticSize};
use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField};
use ast::{StructVariantKind, BiSub};
use ast::StrStyle;
use ast_util;
use codemap::{Span, BytePos, Spanned, spanned, mk_sp};
use codemap;
+use parse;
use parse::attr::ParserAttr;
use parse::classify;
use parse::common::{SeqSep, seq_sep_none};
}
enum ItemOrViewItem {
- // Indicates a failure to parse any kind of item. The attributes are
- // returned.
+ /// Indicates a failure to parse any kind of item. The attributes are
+ /// returned.
IoviNone(Vec<Attribute>),
IoviItem(Gc<Item>),
IoviForeignItem(Gc<ForeignItem>),
}
-// Possibly accept an `INTERPOLATED` expression (a pre-parsed expression
-// dropped into the token stream, which happens while parsing the
-// result of macro expansion)
-/* Placement of these is not as complex as I feared it would be.
-The important thing is to make sure that lookahead doesn't balk
-at INTERPOLATED tokens */
+/// Possibly accept an `INTERPOLATED` expression (a pre-parsed expression
+/// dropped into the token stream, which happens while parsing the
+/// result of macro expansion)
+/// Placement of these is not as complex as I feared it would be.
+/// The important thing is to make sure that lookahead doesn't balk
+/// at INTERPOLATED tokens
macro_rules! maybe_whole_expr (
($p:expr) => (
{
)
)
-// As above, but for things other than expressions
+/// As maybe_whole_expr, but for things other than expressions
macro_rules! maybe_whole (
($p:expr, $constructor:ident) => (
{
pub struct Parser<'a> {
pub sess: &'a ParseSess,
- // the current token:
+ /// the current token:
pub token: token::Token,
- // the span of the current token:
+ /// the span of the current token:
pub span: Span,
- // the span of the prior token:
+ /// the span of the prior token:
pub last_span: Span,
pub cfg: CrateConfig,
- // the previous token or None (only stashed sometimes).
+ /// the previous token or None (only stashed sometimes).
pub last_token: Option<Box<token::Token>>,
pub buffer: [TokenAndSpan, ..4],
pub buffer_start: int,
is_plain_ident(t) || *t == token::UNDERSCORE
}
+/// Get a token the parser cares about
+fn real_token(rdr: &mut Reader) -> TokenAndSpan {
+ let mut t = rdr.next_token();
+ loop {
+ match t.tok {
+ token::WS | token::COMMENT | token::SHEBANG(_) => {
+ t = rdr.next_token();
+ },
+ _ => break
+ }
+ }
+ t
+}
+
impl<'a> Parser<'a> {
pub fn new(sess: &'a ParseSess, cfg: ast::CrateConfig,
mut rdr: Box<Reader>) -> Parser<'a> {
- let tok0 = rdr.next_token();
+ let tok0 = real_token(rdr);
let span = tok0.sp;
let placeholder = TokenAndSpan {
tok: token::UNDERSCORE,
root_module_name: None,
}
}
- // convert a token to a string using self's reader
- pub fn token_to_str(token: &token::Token) -> String {
- token::to_str(token)
+
+ /// Convert a token to a string using self's reader
+ pub fn token_to_string(token: &token::Token) -> String {
+ token::to_string(token)
}
- // convert the current token to a string using self's reader
- pub fn this_token_to_str(&mut self) -> String {
- Parser::token_to_str(&self.token)
+ /// Convert the current token to a string using self's reader
+ pub fn this_token_to_string(&mut self) -> String {
+ Parser::token_to_string(&self.token)
}
pub fn unexpected_last(&mut self, t: &token::Token) -> ! {
- let token_str = Parser::token_to_str(t);
+ let token_str = Parser::token_to_string(t);
let last_span = self.last_span;
self.span_fatal(last_span, format!("unexpected token: `{}`",
token_str).as_slice());
}
pub fn unexpected(&mut self) -> ! {
- let this_token = self.this_token_to_str();
+ let this_token = self.this_token_to_string();
self.fatal(format!("unexpected token: `{}`", this_token).as_slice());
}
- // expect and consume the token t. Signal an error if
- // the next token is not t.
+ /// Expect and consume the token t. Signal an error if
+ /// the next token is not t.
pub fn expect(&mut self, t: &token::Token) {
if self.token == *t {
self.bump();
} else {
- let token_str = Parser::token_to_str(t);
- let this_token_str = self.this_token_to_str();
+ let token_str = Parser::token_to_string(t);
+ let this_token_str = self.this_token_to_string();
self.fatal(format!("expected `{}` but found `{}`",
token_str,
this_token_str).as_slice())
}
}
- // Expect next token to be edible or inedible token. If edible,
- // then consume it; if inedible, then return without consuming
- // anything. Signal a fatal error if next token is unexpected.
+ /// Expect next token to be edible or inedible token. If edible,
+ /// then consume it; if inedible, then return without consuming
+ /// anything. Signal a fatal error if next token is unexpected.
pub fn expect_one_of(&mut self,
edible: &[token::Token],
inedible: &[token::Token]) {
- fn tokens_to_str(tokens: &[token::Token]) -> String {
+ fn tokens_to_string(tokens: &[token::Token]) -> String {
let mut i = tokens.iter();
// This might be a sign we need a connect method on Iterator.
let b = i.next()
- .map_or("".to_string(), |t| Parser::token_to_str(t));
+ .map_or("".to_string(), |t| Parser::token_to_string(t));
i.fold(b, |b,a| {
let mut b = b;
b.push_str("`, `");
- b.push_str(Parser::token_to_str(a).as_slice());
+ b.push_str(Parser::token_to_string(a).as_slice());
b
})
}
// leave it in the input
} else {
let expected = edible.iter().map(|x| (*x).clone()).collect::<Vec<_>>().append(inedible);
- let expect = tokens_to_str(expected.as_slice());
- let actual = self.this_token_to_str();
+ let expect = tokens_to_string(expected.as_slice());
+ let actual = self.this_token_to_string();
self.fatal(
(if expected.len() != 1 {
(format!("expected one of `{}` but found `{}`",
}
}
- // Check for erroneous `ident { }`; if matches, signal error and
- // recover (without consuming any expected input token). Returns
- // true if and only if input was consumed for recovery.
+ /// Check for erroneous `ident { }`; if matches, signal error and
+ /// recover (without consuming any expected input token). Returns
+ /// true if and only if input was consumed for recovery.
pub fn check_for_erroneous_unit_struct_expecting(&mut self, expected: &[token::Token]) -> bool {
if self.token == token::LBRACE
&& expected.iter().all(|t| *t != token::LBRACE)
}
}
- // Commit to parsing a complete expression `e` expected to be
- // followed by some token from the set edible + inedible. Recover
- // from anticipated input errors, discarding erroneous characters.
+ /// Commit to parsing a complete expression `e` expected to be
+ /// followed by some token from the set edible + inedible. Recover
+ /// from anticipated input errors, discarding erroneous characters.
pub fn commit_expr(&mut self, e: Gc<Expr>, edible: &[token::Token],
inedible: &[token::Token]) {
debug!("commit_expr {:?}", e);
self.commit_expr(e, &[edible], &[])
}
- // Commit to parsing a complete statement `s`, which expects to be
- // followed by some token from the set edible + inedible. Check
- // for recoverable input errors, discarding erroneous characters.
+ /// Commit to parsing a complete statement `s`, which expects to be
+ /// followed by some token from the set edible + inedible. Check
+ /// for recoverable input errors, discarding erroneous characters.
pub fn commit_stmt(&mut self, s: Gc<Stmt>, edible: &[token::Token],
inedible: &[token::Token]) {
debug!("commit_stmt {:?}", s);
self.bug("ident interpolation not converted to real token");
}
_ => {
- let token_str = self.this_token_to_str();
+ let token_str = self.this_token_to_string();
self.fatal((format!("expected ident, found `{}`",
token_str)).as_slice())
}
id: ast::DUMMY_NODE_ID })
}
- // consume token 'tok' if it exists. Returns true if the given
- // token was present, false otherwise.
+ /// Consume token 'tok' if it exists. Returns true if the given
+ /// token was present, false otherwise.
pub fn eat(&mut self, tok: &token::Token) -> bool {
let is_present = self.token == *tok;
if is_present { self.bump() }
token::is_keyword(kw, &self.token)
}
- // if the next token is the given keyword, eat it and return
- // true. Otherwise, return false.
+ /// If the next token is the given keyword, eat it and return
+ /// true. Otherwise, return false.
pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> bool {
- let is_kw = match self.token {
- token::IDENT(sid, false) => kw.to_ident().name == sid.name,
+ match self.token {
+ token::IDENT(sid, false) if kw.to_name() == sid.name => {
+ self.bump();
+ true
+ }
_ => false
- };
- if is_kw { self.bump() }
- is_kw
+ }
}
- // if the given word is not a keyword, signal an error.
- // if the next token is not the given word, signal an error.
- // otherwise, eat it.
+ /// If the given word is not a keyword, signal an error.
+ /// If the next token is not the given word, signal an error.
+ /// Otherwise, eat it.
pub fn expect_keyword(&mut self, kw: keywords::Keyword) {
if !self.eat_keyword(kw) {
- let id_interned_str = token::get_ident(kw.to_ident());
- let token_str = self.this_token_to_str();
+ let id_interned_str = token::get_name(kw.to_name());
+ let token_str = self.this_token_to_string();
self.fatal(format!("expected `{}`, found `{}`",
id_interned_str, token_str).as_slice())
}
}
- // signal an error if the given string is a strict keyword
+ /// Signal an error if the given string is a strict keyword
pub fn check_strict_keywords(&mut self) {
if token::is_strict_keyword(&self.token) {
- let token_str = self.this_token_to_str();
+ let token_str = self.this_token_to_string();
let span = self.span;
self.span_err(span,
format!("found `{}` in ident position",
}
}
- // signal an error if the current token is a reserved keyword
+ /// Signal an error if the current token is a reserved keyword
pub fn check_reserved_keywords(&mut self) {
if token::is_reserved_keyword(&self.token) {
- let token_str = self.this_token_to_str();
+ let token_str = self.this_token_to_string();
self.fatal(format!("`{}` is a reserved keyword",
token_str).as_slice())
}
}
- // Expect and consume an `&`. If `&&` is seen, replace it with a single
- // `&` and continue. If an `&` is not seen, signal an error.
+ /// Expect and consume an `&`. If `&&` is seen, replace it with a single
+ /// `&` and continue. If an `&` is not seen, signal an error.
fn expect_and(&mut self) {
match self.token {
token::BINOP(token::AND) => self.bump(),
self.replace_token(token::BINOP(token::AND), lo, span.hi)
}
_ => {
- let token_str = self.this_token_to_str();
+ let token_str = self.this_token_to_string();
let found_token =
- Parser::token_to_str(&token::BINOP(token::AND));
+ Parser::token_to_string(&token::BINOP(token::AND));
self.fatal(format!("expected `{}`, found `{}`",
found_token,
token_str).as_slice())
}
}
- // Expect and consume a `|`. If `||` is seen, replace it with a single
- // `|` and continue. If a `|` is not seen, signal an error.
+ /// Expect and consume a `|`. If `||` is seen, replace it with a single
+ /// `|` and continue. If a `|` is not seen, signal an error.
fn expect_or(&mut self) {
match self.token {
token::BINOP(token::OR) => self.bump(),
self.replace_token(token::BINOP(token::OR), lo, span.hi)
}
_ => {
- let found_token = self.this_token_to_str();
+ let found_token = self.this_token_to_string();
let token_str =
- Parser::token_to_str(&token::BINOP(token::OR));
+ Parser::token_to_string(&token::BINOP(token::OR));
self.fatal(format!("expected `{}`, found `{}`",
token_str,
found_token).as_slice())
}
}
- // Attempt to consume a `<`. If `<<` is seen, replace it with a single
- // `<` and continue. If a `<` is not seen, return false.
- //
- // This is meant to be used when parsing generics on a path to get the
- // starting token. The `force` parameter is used to forcefully break up a
- // `<<` token. If `force` is false, then `<<` is only broken when a lifetime
- // shows up next. For example, consider the expression:
- //
- // foo as bar << test
- //
- // The parser needs to know if `bar <<` is the start of a generic path or if
- // it's a left-shift token. If `test` were a lifetime, then it's impossible
- // for the token to be a left-shift, but if it's not a lifetime, then it's
- // considered a left-shift.
- //
- // The reason for this is that the only current ambiguity with `<<` is when
- // parsing closure types:
- //
- // foo::<<'a> ||>();
- // impl Foo<<'a> ||>() { ... }
+ /// Attempt to consume a `<`. If `<<` is seen, replace it with a single
+ /// `<` and continue. If a `<` is not seen, return false.
+ ///
+ /// This is meant to be used when parsing generics on a path to get the
+ /// starting token. The `force` parameter is used to forcefully break up a
+ /// `<<` token. If `force` is false, then `<<` is only broken when a lifetime
+ /// shows up next. For example, consider the expression:
+ ///
+ /// foo as bar << test
+ ///
+ /// The parser needs to know if `bar <<` is the start of a generic path or if
+ /// it's a left-shift token. If `test` were a lifetime, then it's impossible
+ /// for the token to be a left-shift, but if it's not a lifetime, then it's
+ /// considered a left-shift.
+ ///
+ /// The reason for this is that the only current ambiguity with `<<` is when
+ /// parsing closure types:
+ ///
+ /// foo::<<'a> ||>();
+ /// impl Foo<<'a> ||>() { ... }
fn eat_lt(&mut self, force: bool) -> bool {
match self.token {
token::LT => { self.bump(); true }
fn expect_lt(&mut self) {
if !self.eat_lt(true) {
- let found_token = self.this_token_to_str();
- let token_str = Parser::token_to_str(&token::LT);
+ let found_token = self.this_token_to_string();
+ let token_str = Parser::token_to_string(&token::LT);
self.fatal(format!("expected `{}`, found `{}`",
token_str,
found_token).as_slice())
}
}
- // Parse a sequence bracketed by `|` and `|`, stopping before the `|`.
+ /// Parse a sequence bracketed by `|` and `|`, stopping before the `|`.
fn parse_seq_to_before_or<T>(
&mut self,
sep: &token::Token,
vector
}
- // expect and consume a GT. if a >> is seen, replace it
- // with a single > and continue. If a GT is not seen,
- // signal an error.
+ /// Expect and consume a GT. if a >> is seen, replace it
+ /// with a single > and continue. If a GT is not seen,
+ /// signal an error.
pub fn expect_gt(&mut self) {
match self.token {
token::GT => self.bump(),
self.replace_token(token::EQ, lo, span.hi)
}
_ => {
- let gt_str = Parser::token_to_str(&token::GT);
- let this_token_str = self.this_token_to_str();
+ let gt_str = Parser::token_to_string(&token::GT);
+ let this_token_str = self.this_token_to_string();
self.fatal(format!("expected `{}`, found `{}`",
gt_str,
this_token_str).as_slice())
}
}
- // parse a sequence bracketed by '<' and '>', stopping
- // before the '>'.
+ /// Parse a sequence bracketed by '<' and '>', stopping
+ /// before the '>'.
pub fn parse_seq_to_before_gt<T>(
&mut self,
sep: Option<token::Token>,
return v;
}
- // parse a sequence, including the closing delimiter. The function
- // f must consume tokens until reaching the next separator or
- // closing bracket.
+ /// Parse a sequence, including the closing delimiter. The function
+ /// f must consume tokens until reaching the next separator or
+ /// closing bracket.
pub fn parse_seq_to_end<T>(
&mut self,
ket: &token::Token,
val
}
- // parse a sequence, not including the closing delimiter. The function
- // f must consume tokens until reaching the next separator or
- // closing bracket.
+ /// Parse a sequence, not including the closing delimiter. The function
+ /// f must consume tokens until reaching the next separator or
+ /// closing bracket.
pub fn parse_seq_to_before_end<T>(
&mut self,
ket: &token::Token,
return v;
}
- // parse a sequence, including the closing delimiter. The function
- // f must consume tokens until reaching the next separator or
- // closing bracket.
+ /// Parse a sequence, including the closing delimiter. The function
+ /// f must consume tokens until reaching the next separator or
+ /// closing bracket.
pub fn parse_unspanned_seq<T>(
&mut self,
bra: &token::Token,
result
}
- // parse a sequence parameter of enum variant. For consistency purposes,
- // these should not be empty.
+ /// Parse a sequence parameter of enum variant. For consistency purposes,
+ /// these should not be empty.
pub fn parse_enum_variant_seq<T>(
&mut self,
bra: &token::Token,
spanned(lo, hi, result)
}
- // advance the parser by one token
+ /// Advance the parser by one token
pub fn bump(&mut self) {
self.last_span = self.span;
// Stash token for error recovery (sometimes; clone is not necessarily cheap).
None
};
let next = if self.buffer_start == self.buffer_end {
- self.reader.next_token()
+ real_token(self.reader)
} else {
// Avoid token copies with `replace`.
let buffer_start = self.buffer_start as uint;
self.tokens_consumed += 1u;
}
- // Advance the parser by one token and return the bumped token.
+ /// Advance the parser by one token and return the bumped token.
pub fn bump_and_get(&mut self) -> token::Token {
let old_token = replace(&mut self.token, token::UNDERSCORE);
self.bump();
old_token
}
- // EFFECT: replace the current token and span with the given one
+ /// EFFECT: replace the current token and span with the given one
pub fn replace_token(&mut self,
next: token::Token,
lo: BytePos,
-> R {
let dist = distance as int;
while self.buffer_length() < dist {
- self.buffer[self.buffer_end as uint] = self.reader.next_token();
+ self.buffer[self.buffer_end as uint] = real_token(self.reader);
self.buffer_end = (self.buffer_end + 1) & 3;
}
f(&self.buffer[((self.buffer_start + dist - 1) & 3) as uint].tok)
token::get_ident(id)
}
- // Is the current token one of the keywords that signals a bare function
- // type?
+ /// Is the current token one of the keywords that signals a bare function
+ /// type?
pub fn token_is_bare_fn_keyword(&mut self) -> bool {
if token::is_keyword(keywords::Fn, &self.token) {
return true
false
}
- // Is the current token one of the keywords that signals a closure type?
+ /// Is the current token one of the keywords that signals a closure type?
pub fn token_is_closure_keyword(&mut self) -> bool {
token::is_keyword(keywords::Unsafe, &self.token) ||
token::is_keyword(keywords::Once, &self.token)
}
- // Is the current token one of the keywords that signals an old-style
- // closure type (with explicit sigil)?
+ /// Is the current token one of the keywords that signals an old-style
+ /// closure type (with explicit sigil)?
pub fn token_is_old_style_closure_keyword(&mut self) -> bool {
token::is_keyword(keywords::Unsafe, &self.token) ||
token::is_keyword(keywords::Once, &self.token) ||
}
}
- // parse a TyBareFn type:
+ /// parse a TyBareFn type:
pub fn parse_ty_bare_fn(&mut self) -> Ty_ {
/*
});
}
- // Parses a procedure type (`proc`). The initial `proc` keyword must
- // already have been parsed.
+ /// Parses a procedure type (`proc`). The initial `proc` keyword must
+ /// already have been parsed.
pub fn parse_proc_type(&mut self) -> Ty_ {
/*
})
}
- // parse a TyClosure type
+ /// Parse a TyClosure type
pub fn parse_ty_closure(&mut self) -> Ty_ {
/*
}
}
- // parse a function type (following the 'fn')
+ /// Parse a function type (following the 'fn')
pub fn parse_ty_fn_decl(&mut self, allow_variadic: bool)
-> (P<FnDecl>, Vec<ast::Lifetime>) {
/*
(decl, lifetimes)
}
- // parse the methods in a trait declaration
+ /// Parse the methods in a trait declaration
pub fn parse_trait_methods(&mut self) -> Vec<TraitMethod> {
self.parse_unspanned_seq(
&token::LBRACE,
p.parse_inner_attrs_and_block();
let attrs = attrs.append(inner_attrs.as_slice());
Provided(box(GC) ast::Method {
- ident: ident,
attrs: attrs,
- generics: generics,
- explicit_self: explicit_self,
- fn_style: style,
- decl: d,
- body: body,
id: ast::DUMMY_NODE_ID,
span: mk_sp(lo, hi),
- vis: vis,
+ node: ast::MethDecl(ident, generics, explicit_self, style, d, body, vis)
})
}
_ => {
- let token_str = p.this_token_to_str();
+ let token_str = p.this_token_to_string();
p.fatal((format!("expected `;` or `{{` but found `{}`",
token_str)).as_slice())
}
})
}
- // parse a possibly mutable type
+ /// Parse a possibly mutable type
pub fn parse_mt(&mut self) -> MutTy {
let mutbl = self.parse_mutability();
let t = self.parse_ty(true);
MutTy { ty: t, mutbl: mutbl }
}
- // parse [mut/const/imm] ID : TY
- // now used only by obsolete record syntax parser...
+ /// Parse [mut/const/imm] ID : TY
+ /// now used only by obsolete record syntax parser...
pub fn parse_ty_field(&mut self) -> TypeField {
let lo = self.span.lo;
let mutbl = self.parse_mutability();
}
}
- // parse optional return type [ -> TY ] in function decl
+ /// Parse optional return type [ -> TY ] in function decl
pub fn parse_ret_ty(&mut self) -> (RetStyle, P<Ty>) {
return if self.eat(&token::RARROW) {
let lo = self.span.lo;
}
}
- // This version of parse arg doesn't necessarily require
- // identifier names.
+ /// This version of parse arg doesn't necessarily require
+ /// identifier names.
pub fn parse_arg_general(&mut self, require_name: bool) -> Arg {
let pat = if require_name || self.is_named_argument() {
debug!("parse_arg_general parse_pat (require_name:{:?})",
}
}
- // parse a single function argument
+ /// Parse a single function argument
pub fn parse_arg(&mut self) -> Arg {
self.parse_arg_general(true)
}
- // parse an argument in a lambda header e.g. |arg, arg|
+ /// Parse an argument in a lambda header e.g. |arg, arg|
pub fn parse_fn_block_arg(&mut self) -> Arg {
let pat = self.parse_pat();
let t = if self.eat(&token::COLON) {
}
}
- // matches token_lit = LIT_INT | ...
+ /// Matches token_lit = LIT_INTEGER | ...
pub fn lit_from_token(&mut self, tok: &token::Token) -> Lit_ {
match *tok {
- token::LIT_BYTE(i) => LitByte(i),
- token::LIT_CHAR(i) => LitChar(i),
- token::LIT_INT(i, it) => LitInt(i, it),
- token::LIT_UINT(u, ut) => LitUint(u, ut),
- token::LIT_INT_UNSUFFIXED(i) => LitIntUnsuffixed(i),
- token::LIT_FLOAT(s, ft) => {
- LitFloat(self.id_to_interned_str(s), ft)
- }
- token::LIT_FLOAT_UNSUFFIXED(s) => {
- LitFloatUnsuffixed(self.id_to_interned_str(s))
- }
+ token::LIT_BYTE(i) => LitByte(parse::byte_lit(i.as_str()).val0()),
+ token::LIT_CHAR(i) => LitChar(parse::char_lit(i.as_str()).val0()),
+ token::LIT_INTEGER(s) => parse::integer_lit(s.as_str(),
+ &self.sess.span_diagnostic, self.span),
+ token::LIT_FLOAT(s) => parse::float_lit(s.as_str()),
token::LIT_STR(s) => {
- LitStr(self.id_to_interned_str(s), ast::CookedStr)
+ LitStr(token::intern_and_get_ident(parse::str_lit(s.as_str()).as_slice()),
+ ast::CookedStr)
}
token::LIT_STR_RAW(s, n) => {
- LitStr(self.id_to_interned_str(s), ast::RawStr(n))
+ LitStr(token::intern_and_get_ident(parse::raw_str_lit(s.as_str()).as_slice()),
+ ast::RawStr(n))
}
- token::LIT_BINARY_RAW(ref v, _) |
- token::LIT_BINARY(ref v) => LitBinary(v.clone()),
+ token::LIT_BINARY(i) =>
+ LitBinary(parse::binary_lit(i.as_str())),
+ token::LIT_BINARY_RAW(i, _) =>
+ LitBinary(Rc::new(i.as_str().as_bytes().iter().map(|&x| x).collect())),
token::LPAREN => { self.expect(&token::RPAREN); LitNil },
_ => { self.unexpected_last(tok); }
}
}
- // matches lit = true | false | token_lit
+ /// Matches lit = true | false | token_lit
pub fn parse_lit(&mut self) -> Lit {
let lo = self.span.lo;
let lit = if self.eat_keyword(keywords::True) {
codemap::Spanned { node: lit, span: mk_sp(lo, self.last_span.hi) }
}
- // matches '-' lit | lit
+ /// matches '-' lit | lit
pub fn parse_literal_maybe_minus(&mut self) -> Gc<Expr> {
let minus_lo = self.span.lo;
let minus_present = self.eat(&token::BINOP(token::MINUS));
}
/// Parses a single lifetime
- // matches lifetime = LIFETIME
+ /// Matches lifetime = LIFETIME
pub fn parse_lifetime(&mut self) -> ast::Lifetime {
match self.token {
token::LIFETIME(i) => {
token::is_keyword(keywords::Const, tok)
}
- // parse mutability declaration (mut/const/imm)
+ /// Parse mutability declaration (mut/const/imm)
pub fn parse_mutability(&mut self) -> Mutability {
if self.eat_keyword(keywords::Mut) {
MutMutable
}
}
- // parse ident COLON expr
+ /// Parse ident COLON expr
pub fn parse_field(&mut self) -> Field {
let lo = self.span.lo;
let i = self.parse_ident();
}
}
- // at the bottom (top?) of the precedence hierarchy,
- // parse things like parenthesized exprs,
- // macros, return, etc.
+ /// At the bottom (top?) of the precedence hierarchy,
+ /// parse things like parenthesized exprs,
+ /// macros, return, etc.
pub fn parse_bottom_expr(&mut self) -> Gc<Expr> {
maybe_whole_expr!(self);
let ex: Expr_;
- if self.token == token::LPAREN {
- self.bump();
- // (e) is parenthesized e
- // (e,) is a tuple with only one field, e
- let mut trailing_comma = false;
- if self.token == token::RPAREN {
- hi = self.span.hi;
- self.bump();
- let lit = box(GC) spanned(lo, hi, LitNil);
- return self.mk_expr(lo, hi, ExprLit(lit));
- }
- let mut es = vec!(self.parse_expr());
- self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
- while self.token == token::COMMA {
+ match self.token {
+ token::LPAREN => {
self.bump();
- if self.token != token::RPAREN {
- es.push(self.parse_expr());
- self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
+ // (e) is parenthesized e
+ // (e,) is a tuple with only one field, e
+ let mut trailing_comma = false;
+ if self.token == token::RPAREN {
+ hi = self.span.hi;
+ self.bump();
+ let lit = box(GC) spanned(lo, hi, LitNil);
+ return self.mk_expr(lo, hi, ExprLit(lit));
}
- else {
- trailing_comma = true;
+ let mut es = vec!(self.parse_expr());
+ self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
+ while self.token == token::COMMA {
+ self.bump();
+ if self.token != token::RPAREN {
+ es.push(self.parse_expr());
+ self.commit_expr(*es.last().unwrap(), &[], &[token::COMMA, token::RPAREN]);
+ }
+ else {
+ trailing_comma = true;
+ }
}
- }
- hi = self.span.hi;
- self.commit_expr_expecting(*es.last().unwrap(), token::RPAREN);
-
- return if es.len() == 1 && !trailing_comma {
- self.mk_expr(lo, hi, ExprParen(*es.get(0)))
- }
- else {
- self.mk_expr(lo, hi, ExprTup(es))
- }
- } else if self.token == token::LBRACE {
- self.bump();
- let blk = self.parse_block_tail(lo, DefaultBlock);
- return self.mk_expr(blk.span.lo, blk.span.hi,
- ExprBlock(blk));
- } else if token::is_bar(&self.token) {
- return self.parse_lambda_expr();
- } else if self.eat_keyword(keywords::Proc) {
- let decl = self.parse_proc_decl();
- let body = self.parse_expr();
- let fakeblock = P(ast::Block {
- view_items: Vec::new(),
- stmts: Vec::new(),
- expr: Some(body),
- id: ast::DUMMY_NODE_ID,
- rules: DefaultBlock,
- span: body.span,
- });
+ hi = self.span.hi;
+ self.commit_expr_expecting(*es.last().unwrap(), token::RPAREN);
- return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock));
- } else if self.eat_keyword(keywords::Self) {
- let path = ast_util::ident_to_path(mk_sp(lo, hi), special_idents::self_);
- ex = ExprPath(path);
- hi = self.last_span.hi;
- } else if self.eat_keyword(keywords::If) {
- return self.parse_if_expr();
- } else if self.eat_keyword(keywords::For) {
- return self.parse_for_expr(None);
- } else if self.eat_keyword(keywords::While) {
- return self.parse_while_expr();
- } else if Parser::token_is_lifetime(&self.token) {
- let lifetime = self.get_lifetime();
- self.bump();
- self.expect(&token::COLON);
- if self.eat_keyword(keywords::For) {
- return self.parse_for_expr(Some(lifetime))
- } else if self.eat_keyword(keywords::Loop) {
- return self.parse_loop_expr(Some(lifetime))
- } else {
- self.fatal("expected `for` or `loop` after a label")
+ return if es.len() == 1 && !trailing_comma {
+ self.mk_expr(lo, hi, ExprParen(*es.get(0)))
+ }
+ else {
+ self.mk_expr(lo, hi, ExprTup(es))
+ }
+ },
+ token::LBRACE => {
+ self.bump();
+ let blk = self.parse_block_tail(lo, DefaultBlock);
+ return self.mk_expr(blk.span.lo, blk.span.hi,
+ ExprBlock(blk));
+ },
+ token::BINOP(token::OR) | token::OROR => {
+ return self.parse_lambda_expr();
+ },
+ _ if self.eat_keyword(keywords::Proc) => {
+ let decl = self.parse_proc_decl();
+ let body = self.parse_expr();
+ let fakeblock = P(ast::Block {
+ view_items: Vec::new(),
+ stmts: Vec::new(),
+ expr: Some(body),
+ id: ast::DUMMY_NODE_ID,
+ rules: DefaultBlock,
+ span: body.span,
+ });
+ return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock));
+ },
+ // FIXME #13626: Should be able to stick in
+ // token::SELF_KEYWORD_NAME
+ token::IDENT(id @ ast::Ident{
+ name: ast::Name(token::SELF_KEYWORD_NAME_NUM),
+ ctxt: _
+ } ,false) => {
+ self.bump();
+ let path = ast_util::ident_to_path(mk_sp(lo, hi), id);
+ ex = ExprPath(path);
+ hi = self.last_span.hi;
}
- } else if self.eat_keyword(keywords::Loop) {
- return self.parse_loop_expr(None);
- } else if self.eat_keyword(keywords::Continue) {
- let lo = self.span.lo;
- let ex = if Parser::token_is_lifetime(&self.token) {
+ _ if self.eat_keyword(keywords::If) => {
+ return self.parse_if_expr();
+ },
+ _ if self.eat_keyword(keywords::For) => {
+ return self.parse_for_expr(None);
+ },
+ _ if self.eat_keyword(keywords::While) => {
+ return self.parse_while_expr();
+ },
+ _ if Parser::token_is_lifetime(&self.token) => {
let lifetime = self.get_lifetime();
self.bump();
- ExprAgain(Some(lifetime))
- } else {
- ExprAgain(None)
- };
- let hi = self.span.hi;
- return self.mk_expr(lo, hi, ex);
- } else if self.eat_keyword(keywords::Match) {
- return self.parse_match_expr();
- } else if self.eat_keyword(keywords::Unsafe) {
- return self.parse_block_expr(lo, UnsafeBlock(ast::UserProvided));
- } else if self.token == token::LBRACKET {
- self.bump();
-
- if self.token == token::RBRACKET {
- // Empty vector.
- self.bump();
- ex = ExprVec(Vec::new());
- } else {
- // Nonempty vector.
- let first_expr = self.parse_expr();
- if self.token == token::COMMA &&
- self.look_ahead(1, |t| *t == token::DOTDOT) {
- // Repeating vector syntax: [ 0, ..512 ]
+ self.expect(&token::COLON);
+ if self.eat_keyword(keywords::For) {
+ return self.parse_for_expr(Some(lifetime))
+ } else if self.eat_keyword(keywords::Loop) {
+ return self.parse_loop_expr(Some(lifetime))
+ } else {
+ self.fatal("expected `for` or `loop` after a label")
+ }
+ },
+ _ if self.eat_keyword(keywords::Loop) => {
+ return self.parse_loop_expr(None);
+ },
+ _ if self.eat_keyword(keywords::Continue) => {
+ let lo = self.span.lo;
+ let ex = if Parser::token_is_lifetime(&self.token) {
+ let lifetime = self.get_lifetime();
self.bump();
+ ExprAgain(Some(lifetime))
+ } else {
+ ExprAgain(None)
+ };
+ let hi = self.span.hi;
+ return self.mk_expr(lo, hi, ex);
+ },
+ _ if self.eat_keyword(keywords::Match) => {
+ return self.parse_match_expr();
+ },
+ _ if self.eat_keyword(keywords::Unsafe) => {
+ return self.parse_block_expr(lo, UnsafeBlock(ast::UserProvided));
+ },
+ token::LBRACKET => {
+ self.bump();
+
+ if self.token == token::RBRACKET {
+ // Empty vector.
self.bump();
- let count = self.parse_expr();
- self.expect(&token::RBRACKET);
- ex = ExprRepeat(first_expr, count);
- } else if self.token == token::COMMA {
- // Vector with two or more elements.
+ ex = ExprVec(Vec::new());
+ } else {
+ // Nonempty vector.
+ let first_expr = self.parse_expr();
+ if self.token == token::COMMA &&
+ self.look_ahead(1, |t| *t == token::DOTDOT) {
+ // Repeating vector syntax: [ 0, ..512 ]
+ self.bump();
+ self.bump();
+ let count = self.parse_expr();
+ self.expect(&token::RBRACKET);
+ ex = ExprRepeat(first_expr, count);
+ } else if self.token == token::COMMA {
+ // Vector with two or more elements.
+ self.bump();
+ let remaining_exprs = self.parse_seq_to_end(
+ &token::RBRACKET,
+ seq_sep_trailing_allowed(token::COMMA),
+ |p| p.parse_expr()
+ );
+ let mut exprs = vec!(first_expr);
+ exprs.push_all_move(remaining_exprs);
+ ex = ExprVec(exprs);
+ } else {
+ // Vector with one element.
+ self.expect(&token::RBRACKET);
+ ex = ExprVec(vec!(first_expr));
+ }
+ }
+ hi = self.last_span.hi;
+ },
+ _ if self.eat_keyword(keywords::Return) => {
+ // RETURN expression
+ if can_begin_expr(&self.token) {
+ let e = self.parse_expr();
+ hi = e.span.hi;
+ ex = ExprRet(Some(e));
+ } else { ex = ExprRet(None); }
+ },
+ _ if self.eat_keyword(keywords::Break) => {
+ // BREAK expression
+ if Parser::token_is_lifetime(&self.token) {
+ let lifetime = self.get_lifetime();
self.bump();
- let remaining_exprs = self.parse_seq_to_end(
- &token::RBRACKET,
- seq_sep_trailing_allowed(token::COMMA),
- |p| p.parse_expr()
- );
- let mut exprs = vec!(first_expr);
- exprs.push_all_move(remaining_exprs);
- ex = ExprVec(exprs);
+ ex = ExprBreak(Some(lifetime));
} else {
- // Vector with one element.
- self.expect(&token::RBRACKET);
- ex = ExprVec(vec!(first_expr));
+ ex = ExprBreak(None);
}
- }
- hi = self.last_span.hi;
- } else if self.eat_keyword(keywords::Return) {
- // RETURN expression
- if can_begin_expr(&self.token) {
- let e = self.parse_expr();
- hi = e.span.hi;
- ex = ExprRet(Some(e));
- } else { ex = ExprRet(None); }
- } else if self.eat_keyword(keywords::Break) {
- // BREAK expression
- if Parser::token_is_lifetime(&self.token) {
- let lifetime = self.get_lifetime();
- self.bump();
- ex = ExprBreak(Some(lifetime));
- } else {
- ex = ExprBreak(None);
- }
- hi = self.span.hi;
- } else if self.token == token::MOD_SEP ||
+ hi = self.span.hi;
+ },
+ _ if self.token == token::MOD_SEP ||
is_ident(&self.token) && !self.is_keyword(keywords::True) &&
- !self.is_keyword(keywords::False) {
- let pth = self.parse_path(LifetimeAndTypesWithColons).path;
+ !self.is_keyword(keywords::False) => {
+ let pth = self.parse_path(LifetimeAndTypesWithColons).path;
- // `!`, as an operator, is prefix, so we know this isn't that
- if self.token == token::NOT {
- // MACRO INVOCATION expression
- self.bump();
+ // `!`, as an operator, is prefix, so we know this isn't that
+ if self.token == token::NOT {
+ // MACRO INVOCATION expression
+ self.bump();
- let ket = token::close_delimiter_for(&self.token)
- .unwrap_or_else(|| self.fatal("expected open delimiter"));
- self.bump();
+ let ket = token::close_delimiter_for(&self.token)
+ .unwrap_or_else(|| self.fatal("expected open delimiter"));
+ self.bump();
- let tts = self.parse_seq_to_end(&ket,
- seq_sep_none(),
- |p| p.parse_token_tree());
- let hi = self.span.hi;
+ let tts = self.parse_seq_to_end(&ket,
+ seq_sep_none(),
+ |p| p.parse_token_tree());
+ let hi = self.span.hi;
- return self.mk_mac_expr(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT));
- } else if self.token == token::LBRACE {
- // This is a struct literal, unless we're prohibited from
- // parsing struct literals here.
- if self.restriction != RESTRICT_NO_STRUCT_LITERAL {
- // It's a struct literal.
- self.bump();
- let mut fields = Vec::new();
- let mut base = None;
+ return self.mk_mac_expr(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT));
+ } else if self.token == token::LBRACE {
+ // This is a struct literal, unless we're prohibited from
+ // parsing struct literals here.
+ if self.restriction != RESTRICT_NO_STRUCT_LITERAL {
+ // It's a struct literal.
+ self.bump();
+ let mut fields = Vec::new();
+ let mut base = None;
+
+ while self.token != token::RBRACE {
+ if self.eat(&token::DOTDOT) {
+ base = Some(self.parse_expr());
+ break;
+ }
- while self.token != token::RBRACE {
- if self.eat(&token::DOTDOT) {
- base = Some(self.parse_expr());
- break;
+ fields.push(self.parse_field());
+ self.commit_expr(fields.last().unwrap().expr,
+ &[token::COMMA], &[token::RBRACE]);
}
- fields.push(self.parse_field());
- self.commit_expr(fields.last().unwrap().expr,
- &[token::COMMA], &[token::RBRACE]);
- }
+ if fields.len() == 0 && base.is_none() {
+ let last_span = self.last_span;
+ self.span_err(last_span,
+ "structure literal must either have at \
+ least one field or use functional \
+ structure update syntax");
+ }
- if fields.len() == 0 && base.is_none() {
- let last_span = self.last_span;
- self.span_err(last_span,
- "structure literal must either have at \
- least one field or use functional \
- structure update syntax");
+ hi = self.span.hi;
+ self.expect(&token::RBRACE);
+ ex = ExprStruct(pth, fields, base);
+ return self.mk_expr(lo, hi, ex);
}
-
- hi = self.span.hi;
- self.expect(&token::RBRACE);
- ex = ExprStruct(pth, fields, base);
- return self.mk_expr(lo, hi, ex);
}
- }
hi = pth.span.hi;
ex = ExprPath(pth);
- } else {
- // other literal expression
- let lit = self.parse_lit();
- hi = lit.span.hi;
- ex = ExprLit(box(GC) lit);
+ },
+ _ => {
+ // other literal expression
+ let lit = self.parse_lit();
+ hi = lit.span.hi;
+ ex = ExprLit(box(GC) lit);
+ }
}
return self.mk_expr(lo, hi, ex);
}
- // parse a block or unsafe block
+ /// Parse a block or unsafe block
pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode)
-> Gc<Expr> {
self.expect(&token::LBRACE);
return self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk));
}
- // parse a.b or a(13) or a[4] or just a
+ /// parse a.b or a(13) or a[4] or just a
pub fn parse_dot_or_call_expr(&mut self) -> Gc<Expr> {
let b = self.parse_bottom_expr();
self.parse_dot_or_call_expr_with(b)
return e;
}
- // parse an optional separator followed by a kleene-style
- // repetition token (+ or *).
+ /// Parse an optional separator followed by a kleene-style
+ /// repetition token (+ or *).
pub fn parse_sep_and_zerok(&mut self) -> (Option<token::Token>, bool) {
fn parse_zerok(parser: &mut Parser) -> Option<bool> {
match parser.token {
}
}
- // parse a single token tree from the input.
+ /// parse a single token tree from the input.
pub fn parse_token_tree(&mut self) -> TokenTree {
// FIXME #6994: currently, this is too eager. It
// parses token trees but also identifies TTSeq's
None => {}
Some(&sp) => p.span_note(sp, "unclosed delimiter"),
};
- let token_str = p.this_token_to_str();
+ let token_str = p.this_token_to_string();
p.fatal(format!("incorrect close delimiter: `{}`",
token_str).as_slice())
},
}
}
- // This goofy function is necessary to correctly match parens in Matcher's.
- // Otherwise, `$( ( )` would be a valid Matcher, and `$( () )` would be
- // invalid. It's similar to common::parse_seq.
+ /// This goofy function is necessary to correctly match parens in Matcher's.
+ /// Otherwise, `$( ( )` would be a valid Matcher, and `$( () )` would be
+ /// invalid. It's similar to common::parse_seq.
pub fn parse_matcher_subseq_upto(&mut self,
name_idx: &mut uint,
ket: &token::Token)
return spanned(lo, self.span.hi, m);
}
- // parse a prefix-operator expr
+ /// Parse a prefix-operator expr
pub fn parse_prefix_expr(&mut self) -> Gc<Expr> {
let lo = self.span.lo;
let hi;
}
token::BINOP(token::AND) | token::ANDAND => {
self.expect_and();
- let _lt = self.parse_opt_lifetime();
let m = self.parse_mutability();
let e = self.parse_prefix_expr();
hi = e.span.hi;
return self.mk_expr(lo, hi, ex);
}
- // parse an expression of binops
+ /// Parse an expression of binops
pub fn parse_binops(&mut self) -> Gc<Expr> {
let prefix_expr = self.parse_prefix_expr();
self.parse_more_binops(prefix_expr, 0)
}
- // parse an expression of binops of at least min_prec precedence
+ /// Parse an expression of binops of at least min_prec precedence
pub fn parse_more_binops(&mut self, lhs: Gc<Expr>,
min_prec: uint) -> Gc<Expr> {
if self.expr_is_complete(lhs) { return lhs; }
}
}
- // parse an assignment expression....
- // actually, this seems to be the main entry point for
- // parsing an arbitrary expression.
+ /// Parse an assignment expression....
+ /// actually, this seems to be the main entry point for
+ /// parsing an arbitrary expression.
pub fn parse_assign_expr(&mut self) -> Gc<Expr> {
let lo = self.span.lo;
let lhs = self.parse_binops();
}
}
- // parse an 'if' expression ('if' token already eaten)
+ /// Parse an 'if' expression ('if' token already eaten)
pub fn parse_if_expr(&mut self) -> Gc<Expr> {
let lo = self.last_span.lo;
let cond = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
self.mk_expr(lo, hi, ExprIf(cond, thn, els))
}
- // `|args| { ... }` or `{ ...}` like in `do` expressions
+ /// `|args| { ... }` or `{ ...}` like in `do` expressions
pub fn parse_lambda_block_expr(&mut self) -> Gc<Expr> {
self.parse_lambda_expr_(
|p| {
})
}
- // `|args| expr`
+ /// `|args| expr`
pub fn parse_lambda_expr(&mut self) -> Gc<Expr> {
self.parse_lambda_expr_(|p| p.parse_fn_block_decl(),
|p| p.parse_expr())
}
- // parse something of the form |args| expr
- // this is used both in parsing a lambda expr
- // and in parsing a block expr as e.g. in for...
+ /// parse something of the form |args| expr
+ /// this is used both in parsing a lambda expr
+ /// and in parsing a block expr as e.g. in for...
pub fn parse_lambda_expr_(&mut self,
parse_decl: |&mut Parser| -> P<FnDecl>,
parse_body: |&mut Parser| -> Gc<Expr>)
}
}
- // parse a 'for' .. 'in' expression ('for' token already eaten)
+ /// Parse a 'for' .. 'in' expression ('for' token already eaten)
pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>) -> Gc<Expr> {
// Parse: `for <src_pat> in <src_expr> <src_loop_block>`
return self.mk_expr(lo, hi, ExprMatch(discriminant, arms));
}
- // parse an expression
+ /// Parse an expression
pub fn parse_expr(&mut self) -> Gc<Expr> {
return self.parse_expr_res(UNRESTRICTED);
}
- // parse an expression, subject to the given restriction
+ /// Parse an expression, subject to the given restriction
pub fn parse_expr_res(&mut self, r: restriction) -> Gc<Expr> {
let old = self.restriction;
self.restriction = r;
return e;
}
- // parse the RHS of a local variable declaration (e.g. '= 14;')
+ /// Parse the RHS of a local variable declaration (e.g. '= 14;')
fn parse_initializer(&mut self) -> Option<Gc<Expr>> {
if self.token == token::EQ {
self.bump();
}
}
- // parse patterns, separated by '|' s
+ /// Parse patterns, separated by '|' s
fn parse_pats(&mut self) -> Vec<Gc<Pat>> {
let mut pats = Vec::new();
loop {
(before, slice, after)
}
- // parse the fields of a struct-like pattern
+ /// Parse the fields of a struct-like pattern
fn parse_pat_fields(&mut self) -> (Vec<ast::FieldPat> , bool) {
let mut fields = Vec::new();
let mut etc = false;
if self.token == token::DOTDOT {
self.bump();
if self.token != token::RBRACE {
- let token_str = self.this_token_to_str();
+ let token_str = self.this_token_to_string();
self.fatal(format!("expected `{}`, found `{}`", "}",
token_str).as_slice())
}
let subpat = if self.token == token::COLON {
match bind_type {
BindByRef(..) | BindByValue(MutMutable) => {
- let token_str = self.this_token_to_str();
+ let token_str = self.this_token_to_string();
self.fatal(format!("unexpected `{}`",
token_str).as_slice())
}
return (fields, etc);
}
- // parse a pattern.
+ /// Parse a pattern.
pub fn parse_pat(&mut self) -> Gc<Pat> {
maybe_whole!(self, NtPat);
}
}
- // parse ident or ident @ pat
- // used by the copy foo and ref foo patterns to give a good
- // error message when parsing mistakes like ref foo(a,b)
+ /// Parse ident or ident @ pat
+ /// used by the copy foo and ref foo patterns to give a good
+ /// error message when parsing mistakes like ref foo(a,b)
fn parse_pat_ident(&mut self,
binding_mode: ast::BindingMode)
-> ast::Pat_ {
self.span_fatal(last_span,
"expected identifier, found path");
}
- // why a path here, and not just an identifier?
- let name = codemap::Spanned{span: self.last_span, node: self.parse_ident()};
+ let ident = self.parse_ident();
+ let last_span = self.last_span;
+ let name = codemap::Spanned{span: last_span, node: ident};
let sub = if self.eat(&token::AT) {
Some(self.parse_pat())
} else {
PatIdent(binding_mode, name, sub)
}
- // parse a local variable declaration
+ /// Parse a local variable declaration
fn parse_local(&mut self) -> Gc<Local> {
let lo = self.span.lo;
let pat = self.parse_pat();
}
}
- // parse a "let" stmt
+ /// Parse a "let" stmt
fn parse_let(&mut self) -> Gc<Decl> {
let lo = self.span.lo;
let local = self.parse_local();
box(GC) spanned(lo, self.last_span.hi, DeclLocal(local))
}
- // parse a structure field
+ /// Parse a structure field
fn parse_name_and_ty(&mut self, pr: Visibility,
attrs: Vec<Attribute> ) -> StructField {
let lo = self.span.lo;
})
}
- // parse a statement. may include decl.
- // precondition: any attributes are parsed already
+ /// Parse a statement. may include decl.
+ /// Precondition: any attributes are parsed already
pub fn parse_stmt(&mut self, item_attrs: Vec<Attribute>) -> Gc<Stmt> {
maybe_whole!(self, NtStmt);
} else if is_ident(&self.token)
&& !token::is_any_keyword(&self.token)
&& self.look_ahead(1, |t| *t == token::NOT) {
- // parse a macro invocation. Looks like there's serious
- // overlap here; if this clause doesn't catch it (and it
- // won't, for brace-delimited macros) it will fall through
- // to the macro clause of parse_item_or_view_item. This
- // could use some cleanup, it appears to me.
-
- // whoops! I now have a guess: I'm guessing the "parens-only"
- // rule here is deliberate, to allow macro users to use parens
- // for things that should be parsed as stmt_mac, and braces
- // for things that should expand into items. Tricky, and
- // somewhat awkward... and probably undocumented. Of course,
- // I could just be wrong.
+ // it's a macro invocation:
check_expected_item(self, !item_attrs.is_empty());
} else {
""
};
- let tok_str = self.this_token_to_str();
+ let tok_str = self.this_token_to_string();
self.fatal(format!("expected {}`(` or `{{`, but found `{}`",
ident_str,
tok_str).as_slice())
}
}
- // is this expression a successfully-parsed statement?
+ /// Is this expression a successfully-parsed statement?
fn expr_is_complete(&mut self, e: Gc<Expr>) -> bool {
return self.restriction == RESTRICT_STMT_EXPR &&
!classify::expr_requires_semi_to_be_stmt(e);
}
- // parse a block. No inner attrs are allowed.
+ /// Parse a block. No inner attrs are allowed.
pub fn parse_block(&mut self) -> P<Block> {
maybe_whole!(no_clone self, NtBlock);
return self.parse_block_tail_(lo, DefaultBlock, Vec::new());
}
- // parse a block. Inner attrs are allowed.
+ /// Parse a block. Inner attrs are allowed.
fn parse_inner_attrs_and_block(&mut self)
-> (Vec<Attribute> , P<Block>) {
(inner, self.parse_block_tail_(lo, DefaultBlock, next))
}
- // Precondition: already parsed the '{' or '#{'
- // I guess that also means "already parsed the 'impure'" if
- // necessary, and this should take a qualifier.
- // some blocks start with "#{"...
+ /// Precondition: already parsed the '{' or '#{'
+ /// I guess that also means "already parsed the 'impure'" if
+ /// necessary, and this should take a qualifier.
+ /// Some blocks start with "#{"...
fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
self.parse_block_tail_(lo, s, Vec::new())
}
- // parse the rest of a block expression or function body
+ /// Parse the rest of a block expression or function body
fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
first_item_attrs: Vec<Attribute> ) -> P<Block> {
let mut stmts = Vec::new();
}
}
- // matches bounds = ( boundseq )?
- // where boundseq = ( bound + boundseq ) | bound
- // and bound = 'static | ty
- // Returns "None" if there's no colon (e.g. "T");
- // Returns "Some(Empty)" if there's a colon but nothing after (e.g. "T:")
- // Returns "Some(stuff)" otherwise (e.g. "T:stuff").
- // NB: The None/Some distinction is important for issue #7264.
- //
- // Note that the `allow_any_lifetime` argument is a hack for now while the
- // AST doesn't support arbitrary lifetimes in bounds on type parameters. In
- // the future, this flag should be removed, and the return value of this
- // function should be Option<~[TyParamBound]>
+ /// matches optbounds = ( ( : ( boundseq )? )? )
+ /// where boundseq = ( bound + boundseq ) | bound
+ /// and bound = 'static | ty
+ /// Returns "None" if there's no colon (e.g. "T");
+ /// Returns "Some(Empty)" if there's a colon but nothing after (e.g. "T:")
+ /// Returns "Some(stuff)" otherwise (e.g. "T:stuff").
+ /// NB: The None/Some distinction is important for issue #7264.
+ ///
+ /// Note that the `allow_any_lifetime` argument is a hack for now while the
+ /// AST doesn't support arbitrary lifetimes in bounds on type parameters. In
+ /// the future, this flag should be removed, and the return value of this
+ /// function should be Option<~[TyParamBound]>
fn parse_ty_param_bounds(&mut self, allow_any_lifetime: bool)
-> (Option<ast::Lifetime>,
OwnedSlice<TyParamBound>) {
return (ret_lifetime, OwnedSlice::from_vec(result));
}
- // matches typaram = type? IDENT optbounds ( EQ ty )?
+ fn trait_ref_from_ident(ident: Ident, span: Span) -> ast::TraitRef {
+ let segment = ast::PathSegment {
+ identifier: ident,
+ lifetimes: Vec::new(),
+ types: OwnedSlice::empty(),
+ };
+ let path = ast::Path {
+ span: span,
+ global: false,
+ segments: vec![segment],
+ };
+ ast::TraitRef {
+ path: path,
+ ref_id: ast::DUMMY_NODE_ID,
+ }
+ }
+
+ /// Matches typaram = (unbound`?`)? IDENT optbounds ( EQ ty )?
fn parse_ty_param(&mut self) -> TyParam {
- let sized = self.parse_sized();
- let span = self.span;
- let ident = self.parse_ident();
+ // This is a bit hacky. Currently we are only interested in a single
+ // unbound, and it may only be `Sized`. To avoid backtracking and other
+ // complications, we parse an ident, then check for `?`. If we find it,
+ // we use the ident as the unbound, otherwise, we use it as the name of
+ // type param.
+ let mut span = self.span;
+ let mut ident = self.parse_ident();
+ let mut unbound = None;
+ if self.eat(&token::QUESTION) {
+ let tref = Parser::trait_ref_from_ident(ident, span);
+ unbound = Some(TraitTyParamBound(tref));
+ span = self.span;
+ ident = self.parse_ident();
+ }
+
let opt_bounds = {
if self.eat(&token::COLON) {
let (_, bounds) = self.parse_ty_param_bounds(false);
TyParam {
ident: ident,
id: ast::DUMMY_NODE_ID,
- sized: sized,
bounds: bounds,
+ unbound: unbound,
default: default,
span: span,
}
}
- // parse a set of optional generic type parameter declarations
- // matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
- // | ( < lifetimes , typaramseq ( , )? > )
- // where typaramseq = ( typaram ) | ( typaram , typaramseq )
+ /// Parse a set of optional generic type parameter declarations
+ /// matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
+ /// | ( < lifetimes , typaramseq ( , )? > )
+ /// where typaramseq = ( typaram ) | ( typaram , typaramseq )
pub fn parse_generics(&mut self) -> ast::Generics {
if self.eat(&token::LT) {
let lifetimes = self.parse_lifetimes();
(args, variadic)
}
- // parse the argument list and result type of a function declaration
+ /// Parse the argument list and result type of a function declaration
pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> P<FnDecl> {
let (args, variadic) = self.parse_fn_args(true, allow_variadic);
}
}
- fn expect_self_ident(&mut self) {
- if !self.is_self_ident() {
- let token_str = self.this_token_to_str();
- self.fatal(format!("expected `self` but found `{}`",
- token_str).as_slice())
+ fn expect_self_ident(&mut self) -> ast::Ident {
+ match self.token {
+ token::IDENT(id, false) if id.name == special_idents::self_.name => {
+ self.bump();
+ id
+ },
+ _ => {
+ let token_str = self.this_token_to_string();
+ self.fatal(format!("expected `self` but found `{}`",
+ token_str).as_slice())
+ }
}
- self.bump();
}
- // parse the argument list and result type of a function
- // that may have a self type.
+ /// Parse the argument list and result type of a function
+ /// that may have a self type.
fn parse_fn_decl_with_self(&mut self, parse_arg_fn: |&mut Parser| -> Arg)
-> (ExplicitSelf, P<FnDecl>) {
fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
if this.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) {
this.bump();
- this.expect_self_ident();
- SelfRegion(None, MutImmutable)
+ SelfRegion(None, MutImmutable, this.expect_self_ident())
} else if this.look_ahead(1, |t| Parser::token_is_mutability(t)) &&
this.look_ahead(2,
|t| token::is_keyword(keywords::Self,
t)) {
this.bump();
let mutability = this.parse_mutability();
- this.expect_self_ident();
- SelfRegion(None, mutability)
+ SelfRegion(None, mutability, this.expect_self_ident())
} else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) &&
this.look_ahead(2,
|t| token::is_keyword(keywords::Self,
t)) {
this.bump();
let lifetime = this.parse_lifetime();
- this.expect_self_ident();
- SelfRegion(Some(lifetime), MutImmutable)
+ SelfRegion(Some(lifetime), MutImmutable, this.expect_self_ident())
} else if this.look_ahead(1, |t| Parser::token_is_lifetime(t)) &&
this.look_ahead(2, |t| {
Parser::token_is_mutability(t)
this.bump();
let lifetime = this.parse_lifetime();
let mutability = this.parse_mutability();
- this.expect_self_ident();
- SelfRegion(Some(lifetime), mutability)
+ SelfRegion(Some(lifetime), mutability, this.expect_self_ident())
} else {
SelfStatic
}
// We need to make sure it isn't a type
if self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) {
self.bump();
- self.expect_self_ident();
- SelfUniq
+ SelfUniq(self.expect_self_ident())
} else {
SelfStatic
}
}
token::IDENT(..) if self.is_self_ident() => {
- self.bump();
- SelfValue
+ SelfValue(self.expect_self_ident())
}
token::BINOP(token::STAR) => {
// Possibly "*self" or "*mut self" -- not supported. Try to avoid
self.span_err(span, "cannot pass self by unsafe pointer");
self.bump();
}
- SelfValue
+ // error case, making bogus self ident:
+ SelfValue(special_idents::self_)
}
_ if Parser::token_is_mutability(&self.token) &&
self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => {
mutbl_self = self.parse_mutability();
- self.expect_self_ident();
- SelfValue
+ SelfValue(self.expect_self_ident())
}
_ if Parser::token_is_mutability(&self.token) &&
self.look_ahead(1, |t| *t == token::TILDE) &&
self.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) => {
mutbl_self = self.parse_mutability();
self.bump();
- self.expect_self_ident();
- SelfUniq
+ SelfUniq(self.expect_self_ident())
}
_ => SelfStatic
};
let explicit_self_sp = mk_sp(lo, self.span.hi);
- // If we parsed a self type, expect a comma before the argument list.
- let fn_inputs = if explicit_self != SelfStatic {
+ // shared fall-through for the three cases below. borrowing prevents simply
+ // writing this as a closure
+ macro_rules! parse_remaining_arguments {
+ ($self_id:ident) =>
+ {
+ // If we parsed a self type, expect a comma before the argument list.
match self.token {
token::COMMA => {
self.bump();
sep,
parse_arg_fn
);
- fn_inputs.unshift(Arg::new_self(explicit_self_sp, mutbl_self));
+ fn_inputs.unshift(Arg::new_self(explicit_self_sp, mutbl_self, $self_id));
fn_inputs
}
token::RPAREN => {
- vec!(Arg::new_self(explicit_self_sp, mutbl_self))
+ vec!(Arg::new_self(explicit_self_sp, mutbl_self, $self_id))
}
_ => {
- let token_str = self.this_token_to_str();
+ let token_str = self.this_token_to_string();
self.fatal(format!("expected `,` or `)`, found `{}`",
token_str).as_slice())
}
}
- } else {
- let sep = seq_sep_trailing_disallowed(token::COMMA);
- self.parse_seq_to_before_end(&token::RPAREN, sep, parse_arg_fn)
+ }
+ }
+
+ let fn_inputs = match explicit_self {
+ SelfStatic => {
+ let sep = seq_sep_trailing_disallowed(token::COMMA);
+ self.parse_seq_to_before_end(&token::RPAREN, sep, parse_arg_fn)
+ }
+ SelfValue(id) => parse_remaining_arguments!(id),
+ SelfRegion(_,_,id) => parse_remaining_arguments!(id),
+ SelfUniq(id) => parse_remaining_arguments!(id)
+
};
+
self.expect(&token::RPAREN);
let hi = self.span.hi;
(spanned(lo, hi, explicit_self), fn_decl)
}
- // parse the |arg, arg| header on a lambda
+ /// Parse the |arg, arg| header on a lambda
fn parse_fn_block_decl(&mut self) -> P<FnDecl> {
let inputs_captures = {
if self.eat(&token::OROR) {
})
}
- // Parses the `(arg, arg) -> return_type` header on a procedure.
+ /// Parses the `(arg, arg) -> return_type` header on a procedure.
fn parse_proc_decl(&mut self) -> P<FnDecl> {
let inputs =
self.parse_unspanned_seq(&token::LPAREN,
})
}
- // parse the name and optional generic types of a function header.
+ /// Parse the name and optional generic types of a function header.
fn parse_fn_header(&mut self) -> (Ident, ast::Generics) {
let id = self.parse_ident();
let generics = self.parse_generics();
}
}
- // parse an item-position function declaration.
+ /// Parse an item-position function declaration.
fn parse_item_fn(&mut self, fn_style: FnStyle, abi: abi::Abi) -> ItemInfo {
let (ident, generics) = self.parse_fn_header();
let decl = self.parse_fn_decl(false);
(ident, ItemFn(decl, fn_style, abi, generics, body), Some(inner_attrs))
}
- // parse a method in a trait impl, starting with `attrs` attributes.
- fn parse_method(&mut self,
+ /// Parse a method in a trait impl, starting with `attrs` attributes.
+ pub fn parse_method(&mut self,
already_parsed_attrs: Option<Vec<Attribute>>) -> Gc<Method> {
let next_attrs = self.parse_outer_attributes();
let attrs = match already_parsed_attrs {
let lo = self.span.lo;
- let visa = self.parse_visibility();
- let fn_style = self.parse_fn_style();
- let ident = self.parse_ident();
- let generics = self.parse_generics();
- let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
- p.parse_arg()
- });
+ // code copied from parse_macro_use_or_failure... abstraction!
+ let (method_, hi, new_attrs) = {
+ if !token::is_any_keyword(&self.token)
+ && self.look_ahead(1, |t| *t == token::NOT)
+ && (self.look_ahead(2, |t| *t == token::LPAREN)
+ || self.look_ahead(2, |t| *t == token::LBRACE)) {
+ // method macro.
+ let pth = self.parse_path(NoTypesAllowed).path;
+ self.expect(&token::NOT);
- let (inner_attrs, body) = self.parse_inner_attrs_and_block();
- let hi = body.span.hi;
- let attrs = attrs.append(inner_attrs.as_slice());
+ // eat a matched-delimiter token tree:
+ let tts = match token::close_delimiter_for(&self.token) {
+ Some(ket) => {
+ self.bump();
+ self.parse_seq_to_end(&ket,
+ seq_sep_none(),
+ |p| p.parse_token_tree())
+ }
+ None => self.fatal("expected open delimiter")
+ };
+ let m_ = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
+ let m: ast::Mac = codemap::Spanned { node: m_,
+ span: mk_sp(self.span.lo,
+ self.span.hi) };
+ (ast::MethMac(m), self.span.hi, attrs)
+ } else {
+ let visa = self.parse_visibility();
+ let fn_style = self.parse_fn_style();
+ let ident = self.parse_ident();
+ let generics = self.parse_generics();
+ let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
+ p.parse_arg()
+ });
+ let (inner_attrs, body) = self.parse_inner_attrs_and_block();
+ let new_attrs = attrs.append(inner_attrs.as_slice());
+ (ast::MethDecl(ident, generics, explicit_self, fn_style, decl, body, visa),
+ body.span.hi, new_attrs)
+ }
+ };
box(GC) ast::Method {
- ident: ident,
- attrs: attrs,
- generics: generics,
- explicit_self: explicit_self,
- fn_style: fn_style,
- decl: decl,
- body: body,
+ attrs: new_attrs,
id: ast::DUMMY_NODE_ID,
span: mk_sp(lo, hi),
- vis: visa,
+ node: method_,
}
}
- // parse trait Foo { ... }
+ /// Parse trait Foo { ... }
fn parse_item_trait(&mut self) -> ItemInfo {
let ident = self.parse_ident();
let tps = self.parse_generics();
(ident, ItemTrait(tps, sized, traits, meths), None)
}
- // Parses two variants (with the region/type params always optional):
- // impl<T> Foo { ... }
- // impl<T> ToStr for ~[T] { ... }
+ /// Parses two variants (with the region/type params always optional):
+ /// impl<T> Foo { ... }
+ /// impl<T> ToString for ~[T] { ... }
fn parse_item_impl(&mut self) -> ItemInfo {
// First, parse type parameters if necessary.
let generics = self.parse_generics();
(ident, ItemImpl(generics, opt_trait, ty, meths), Some(inner_attrs))
}
- // parse a::B<String,int>
+ /// Parse a::B<String,int>
fn parse_trait_ref(&mut self) -> TraitRef {
ast::TraitRef {
path: self.parse_path(LifetimeAndTypesWithoutColons).path,
}
}
- // parse B + C<String,int> + D
+ /// Parse B + C<String,int> + D
fn parse_trait_ref_list(&mut self, ket: &token::Token) -> Vec<TraitRef> {
self.parse_seq_to_before_end(
ket,
)
}
- // parse struct Foo { ... }
+ /// Parse struct Foo { ... }
fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo {
let class_name = self.parse_ident();
let generics = self.parse_generics();
is_tuple_like = true;
fields = Vec::new();
} else {
- let token_str = self.this_token_to_str();
+ let token_str = self.this_token_to_string();
self.fatal(format!("expected `{}`, `(`, or `;` after struct \
name but found `{}`", "{",
token_str).as_slice())
None)
}
- // parse a structure field declaration
+ /// Parse a structure field declaration
pub fn parse_single_struct_field(&mut self,
vis: Visibility,
attrs: Vec<Attribute> )
token::RBRACE => {}
_ => {
let span = self.span;
- let token_str = self.this_token_to_str();
+ let token_str = self.this_token_to_string();
self.span_fatal(span,
format!("expected `,`, or `}}` but found `{}`",
token_str).as_slice())
a_var
}
- // parse an element of a struct definition
+ /// Parse an element of a struct definition
fn parse_struct_decl_field(&mut self) -> StructField {
let attrs = self.parse_outer_attributes();
return self.parse_single_struct_field(Inherited, attrs);
}
- // parse visiility: PUB, PRIV, or nothing
+ /// Parse visiility: PUB, PRIV, or nothing
fn parse_visibility(&mut self) -> Visibility {
if self.eat_keyword(keywords::Pub) { Public }
else { Inherited }
}
- fn parse_sized(&mut self) -> Sized {
- if self.eat_keyword(keywords::Type) { DynSize }
- else { StaticSize }
- }
-
- fn parse_for_sized(&mut self) -> Sized {
+ fn parse_for_sized(&mut self) -> Option<ast::TyParamBound> {
if self.eat_keyword(keywords::For) {
- if !self.eat_keyword(keywords::Type) {
- let last_span = self.last_span;
- self.span_err(last_span,
- "expected 'type' after for in trait item");
+ let span = self.span;
+ let ident = self.parse_ident();
+ if !self.eat(&token::QUESTION) {
+ self.span_err(span,
+ "expected 'Sized?' after `for` in trait item");
+ return None;
}
- DynSize
+ let tref = Parser::trait_ref_from_ident(ident, span);
+ Some(TraitTyParamBound(tref))
} else {
- StaticSize
+ None
}
}
- // given a termination token and a vector of already-parsed
- // attributes (of length 0 or 1), parse all of the items in a module
+ /// Given a termination token and a vector of already-parsed
+ /// attributes (of length 0 or 1), parse all of the items in a module
fn parse_mod_items(&mut self,
term: token::Token,
first_item_attrs: Vec<Attribute>,
the module");
}
_ => {
- let token_str = self.this_token_to_str();
+ let token_str = self.this_token_to_string();
self.fatal(format!("expected item but found `{}`",
token_str).as_slice())
}
(id, ItemStatic(ty, m, e), None)
}
- // parse a `mod <foo> { ... }` or `mod <foo>;` item
+ /// Parse a `mod <foo> { ... }` or `mod <foo>;` item
fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> ItemInfo {
let id_span = self.span;
let id = self.parse_ident();
self.mod_path_stack.pop().unwrap();
}
- // read a module from a source file.
+ /// Read a module from a source file.
fn eval_src_mod(&mut self,
id: ast::Ident,
outer_attrs: &[ast::Attribute],
return (ast::ItemMod(m0), mod_attrs);
}
- // parse a function declaration from a foreign module
+ /// Parse a function declaration from a foreign module
fn parse_item_foreign_fn(&mut self, vis: ast::Visibility,
attrs: Vec<Attribute>) -> Gc<ForeignItem> {
let lo = self.span.lo;
vis: vis }
}
- // parse a static item from a foreign module
+ /// Parse a static item from a foreign module
fn parse_item_foreign_static(&mut self, vis: ast::Visibility,
attrs: Vec<Attribute> ) -> Gc<ForeignItem> {
let lo = self.span.lo;
}
}
- // parse safe/unsafe and fn
+ /// Parse safe/unsafe and fn
fn parse_fn_style(&mut self) -> FnStyle {
if self.eat_keyword(keywords::Fn) { NormalFn }
else if self.eat_keyword(keywords::Unsafe) {
}
- // at this point, this is essentially a wrapper for
- // parse_foreign_items.
+ /// At this point, this is essentially a wrapper for
+ /// parse_foreign_items.
fn parse_foreign_mod_items(&mut self,
abi: abi::Abi,
first_item_attrs: Vec<Attribute> )
}
_ => {
let span = self.span;
- let token_str = self.this_token_to_str();
+ let token_str = self.this_token_to_string();
self.span_fatal(span,
format!("expected extern crate name but \
found `{}`",
return IoviItem(item);
}
- // parse type Foo = Bar;
+ /// Parse type Foo = Bar;
fn parse_item_type(&mut self) -> ItemInfo {
let ident = self.parse_ident();
let tps = self.parse_generics();
(ident, ItemTy(ty, tps), None)
}
- // parse a structure-like enum variant definition
- // this should probably be renamed or refactored...
+ /// Parse a structure-like enum variant definition
+ /// this should probably be renamed or refactored...
fn parse_struct_def(&mut self) -> Gc<StructDef> {
let mut fields: Vec<StructField> = Vec::new();
while self.token != token::RBRACE {
};
}
- // parse the part of an "enum" decl following the '{'
+ /// Parse the part of an "enum" decl following the '{'
fn parse_enum_def(&mut self, _generics: &ast::Generics) -> EnumDef {
let mut variants = Vec::new();
let mut all_nullary = true;
ast::EnumDef { variants: variants }
}
- // parse an "enum" declaration
+ /// Parse an "enum" declaration
fn parse_item_enum(&mut self) -> ItemInfo {
let id = self.parse_ident();
let generics = self.parse_generics();
}
}
- // Parses a string as an ABI spec on an extern type or module. Consumes
- // the `extern` keyword, if one is found.
+ /// Parses a string as an ABI spec on an extern type or module. Consumes
+ /// the `extern` keyword, if one is found.
fn parse_opt_abi(&mut self) -> Option<abi::Abi> {
match self.token {
token::LIT_STR(s) | token::LIT_STR_RAW(s, _) => {
self.bump();
- let identifier_string = token::get_ident(s);
- let the_string = identifier_string.get();
+ let the_string = s.as_str();
match abi::lookup(the_string) {
Some(abi) => Some(abi),
None => {
}
}
- // parse one of the items or view items allowed by the
- // flags; on failure, return IoviNone.
- // NB: this function no longer parses the items inside an
- // extern crate.
+ /// Parse one of the items or view items allowed by the
+ /// flags; on failure, return IoviNone.
+ /// NB: this function no longer parses the items inside an
+ /// extern crate.
fn parse_item_or_view_item(&mut self,
attrs: Vec<Attribute> ,
macros_allowed: bool)
}
let span = self.span;
- let token_str = self.this_token_to_str();
+ let token_str = self.this_token_to_string();
self.span_fatal(span,
format!("expected `{}` or `fn` but found `{}`", "{",
token_str).as_slice());
self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
}
- // parse a foreign item; on failure, return IoviNone.
+ /// Parse a foreign item; on failure, return IoviNone.
fn parse_foreign_item(&mut self,
attrs: Vec<Attribute> ,
macros_allowed: bool)
self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
}
- // this is the fall-through for parsing items.
+ /// This is the fall-through for parsing items.
fn parse_macro_use_or_failure(
&mut self,
attrs: Vec<Attribute> ,
}
}
- // parse, e.g., "use a::b::{z,y}"
+ /// Parse, e.g., "use a::b::{z,y}"
fn parse_use(&mut self) -> ViewItem_ {
return ViewItemUse(self.parse_view_path());
}
- // matches view_path : MOD? IDENT EQ non_global_path
- // | MOD? non_global_path MOD_SEP LBRACE RBRACE
- // | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
- // | MOD? non_global_path MOD_SEP STAR
- // | MOD? non_global_path
+ /// Matches view_path : MOD? IDENT EQ non_global_path
+ /// | MOD? non_global_path MOD_SEP LBRACE RBRACE
+ /// | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
+ /// | MOD? non_global_path MOD_SEP STAR
+ /// | MOD? non_global_path
fn parse_view_path(&mut self) -> Gc<ViewPath> {
let lo = self.span.lo;
ViewPathSimple(last, path, ast::DUMMY_NODE_ID));
}
- // Parses a sequence of items. Stops when it finds program
- // text that can't be parsed as an item
- // - mod_items uses extern_mod_allowed = true
- // - block_tail_ uses extern_mod_allowed = false
+ /// Parses a sequence of items. Stops when it finds program
+ /// text that can't be parsed as an item
+ /// - mod_items uses extern_mod_allowed = true
+ /// - block_tail_ uses extern_mod_allowed = false
fn parse_items_and_view_items(&mut self,
first_item_attrs: Vec<Attribute> ,
mut extern_mod_allowed: bool,
}
}
- // Parses a sequence of foreign items. Stops when it finds program
- // text that can't be parsed as an item
+ /// Parses a sequence of foreign items. Stops when it finds program
+ /// text that can't be parsed as an item
fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute> ,
macros_allowed: bool)
-> ParsedItemsAndViewItems {
}
}
- // Parses a source module as a crate. This is the main
- // entry point for the parser.
+ /// Parses a source module as a crate. This is the main
+ /// entry point for the parser.
pub fn parse_crate_mod(&mut self) -> Crate {
let lo = self.span.lo;
// parse the crate's inner attrs, maybe (oops) one
module: m,
attrs: inner,
config: self.cfg.clone(),
- span: mk_sp(lo, self.span.lo)
+ span: mk_sp(lo, self.span.lo),
+ exported_macros: Vec::new(),
}
}
pub fn parse_optional_str(&mut self)
-> Option<(InternedString, ast::StrStyle)> {
let (s, style) = match self.token {
- token::LIT_STR(s) => (self.id_to_interned_str(s), ast::CookedStr),
+ token::LIT_STR(s) => (self.id_to_interned_str(s.ident()), ast::CookedStr),
token::LIT_STR_RAW(s, n) => {
- (self.id_to_interned_str(s), ast::RawStr(n))
+ (self.id_to_interned_str(s.ident()), ast::RawStr(n))
}
_ => return None
};
}
}
}
+
use ast;
use ast::{P, Ident, Name, Mrk};
-use ast_util;
use ext::mtwt;
use parse::token;
use util::interner::{RcStr, StrInterner};
RBRACE,
POUND,
DOLLAR,
+ QUESTION,
/* Literals */
- LIT_BYTE(u8),
- LIT_CHAR(char),
- LIT_INT(i64, ast::IntTy),
- LIT_UINT(u64, ast::UintTy),
- LIT_INT_UNSUFFIXED(i64),
- LIT_FLOAT(ast::Ident, ast::FloatTy),
- LIT_FLOAT_UNSUFFIXED(ast::Ident),
- LIT_STR(ast::Ident),
- LIT_STR_RAW(ast::Ident, uint), /* raw str delimited by n hash symbols */
- LIT_BINARY(Rc<Vec<u8>>),
- LIT_BINARY_RAW(Rc<Vec<u8>>, uint), /* raw binary str delimited by n hash symbols */
+ LIT_BYTE(Name),
+ LIT_CHAR(Name),
+ LIT_INTEGER(Name),
+ LIT_FLOAT(Name),
+ LIT_STR(Name),
+ LIT_STR_RAW(Name, uint), /* raw str delimited by n hash symbols */
+ LIT_BINARY(Name),
+ LIT_BINARY_RAW(Name, uint), /* raw binary str delimited by n hash symbols */
/* Name components */
- // an identifier contains an "is_mod_name" boolean,
- // indicating whether :: follows this token with no
- // whitespace in between.
- IDENT(ast::Ident, bool),
+ /// An identifier contains an "is_mod_name" boolean,
+ /// indicating whether :: follows this token with no
+ /// whitespace in between.
+ IDENT(Ident, bool),
UNDERSCORE,
- LIFETIME(ast::Ident),
+ LIFETIME(Ident),
/* For interpolation */
INTERPOLATED(Nonterminal),
+ DOC_COMMENT(Name),
+
+ // Junk. These carry no data because we don't really care about the data
+ // they *would* carry, and don't really want to allocate a new ident for
+ // them. Instead, users could extract that from the associated span.
+
+ /// Whitespace
+ WS,
+ /// Comment
+ COMMENT,
+ SHEBANG(Name),
- DOC_COMMENT(ast::Ident),
EOF,
}
NtPat( Gc<ast::Pat>),
NtExpr(Gc<ast::Expr>),
NtTy( P<ast::Ty>),
- // see IDENT, above, for meaning of bool in NtIdent:
- NtIdent(Box<ast::Ident>, bool),
- NtMeta(Gc<ast::MetaItem>), // stuff inside brackets for attributes
+ /// See IDENT, above, for meaning of bool in NtIdent:
+ NtIdent(Box<Ident>, bool),
+ /// Stuff inside brackets for attributes
+ NtMeta(Gc<ast::MetaItem>),
NtPath(Box<ast::Path>),
- NtTT( Gc<ast::TokenTree>), // needs @ed to break a circularity
+ NtTT( Gc<ast::TokenTree>), // needs Gc'd to break a circularity
NtMatchers(Vec<ast::Matcher> )
}
}
}
-pub fn binop_to_str(o: BinOp) -> &'static str {
+pub fn binop_to_string(o: BinOp) -> &'static str {
match o {
PLUS => "+",
MINUS => "-",
}
}
-pub fn to_str(t: &Token) -> String {
+pub fn to_string(t: &Token) -> String {
match *t {
EQ => "=".to_string(),
LT => "<".to_string(),
TILDE => "~".to_string(),
OROR => "||".to_string(),
ANDAND => "&&".to_string(),
- BINOP(op) => binop_to_str(op).to_string(),
+ BINOP(op) => binop_to_string(op).to_string(),
BINOPEQ(op) => {
- let mut s = binop_to_str(op).to_string();
+ let mut s = binop_to_string(op).to_string();
s.push_str("=");
s
}
RBRACE => "}".to_string(),
POUND => "#".to_string(),
DOLLAR => "$".to_string(),
+ QUESTION => "?".to_string(),
/* Literals */
LIT_BYTE(b) => {
- let mut res = String::from_str("b'");
- (b as char).escape_default(|c| {
- res.push_char(c);
- });
- res.push_char('\'');
- res
+ format!("b'{}'", b.as_str())
}
LIT_CHAR(c) => {
- let mut res = String::from_str("'");
- c.escape_default(|c| {
- res.push_char(c);
- });
- res.push_char('\'');
- res
- }
- LIT_INT(i, t) => ast_util::int_ty_to_str(t, Some(i)),
- LIT_UINT(u, t) => ast_util::uint_ty_to_str(t, Some(u)),
- LIT_INT_UNSUFFIXED(i) => { (i as u64).to_str() }
- LIT_FLOAT(s, t) => {
- let mut body = String::from_str(get_ident(s).get());
- if body.as_slice().ends_with(".") {
- body.push_char('0'); // `10.f` is not a float literal
- }
- body.push_str(ast_util::float_ty_to_str(t).as_slice());
- body
+ format!("'{}'", c.as_str())
}
- LIT_FLOAT_UNSUFFIXED(s) => {
- let mut body = String::from_str(get_ident(s).get());
- if body.as_slice().ends_with(".") {
- body.push_char('0'); // `10.f` is not a float literal
- }
- body
+ LIT_INTEGER(c) | LIT_FLOAT(c) => {
+ c.as_str().to_string()
}
+
LIT_STR(s) => {
- format!("\"{}\"", get_ident(s).get().escape_default())
+ format!("\"{}\"", s.as_str())
}
LIT_STR_RAW(s, n) => {
format!("r{delim}\"{string}\"{delim}",
- delim="#".repeat(n), string=get_ident(s))
+ delim="#".repeat(n), string=s.as_str())
}
- LIT_BINARY(ref v) => {
- format!(
- "b\"{}\"",
- v.iter().map(|&b| b as char).collect::<String>().escape_default())
+ LIT_BINARY(v) => {
+ format!("b\"{}\"", v.as_str())
}
- LIT_BINARY_RAW(ref s, n) => {
+ LIT_BINARY_RAW(s, n) => {
format!("br{delim}\"{string}\"{delim}",
- delim="#".repeat(n), string=s.as_slice().to_ascii().as_str_ascii())
+ delim="#".repeat(n), string=s.as_str())
}
/* Name components */
UNDERSCORE => "_".to_string(),
/* Other */
- DOC_COMMENT(s) => get_ident(s).get().to_string(),
+ DOC_COMMENT(s) => s.as_str().to_string(),
EOF => "<eof>".to_string(),
+ WS => " ".to_string(),
+ COMMENT => "/* */".to_string(),
+ SHEBANG(s) => format!("/* shebang: {}*/", s.as_str()),
+
INTERPOLATED(ref nt) => {
match nt {
- &NtExpr(ref e) => ::print::pprust::expr_to_str(&**e),
- &NtMeta(ref e) => ::print::pprust::meta_item_to_str(&**e),
+ &NtExpr(ref e) => ::print::pprust::expr_to_string(&**e),
+ &NtMeta(ref e) => ::print::pprust::meta_item_to_string(&**e),
_ => {
let mut s = "an interpolated ".to_string();
match *nt {
TILDE => true,
LIT_BYTE(_) => true,
LIT_CHAR(_) => true,
- LIT_INT(_, _) => true,
- LIT_UINT(_, _) => true,
- LIT_INT_UNSUFFIXED(_) => true,
- LIT_FLOAT(_, _) => true,
- LIT_FLOAT_UNSUFFIXED(_) => true,
+ LIT_INTEGER(_) => true,
+ LIT_FLOAT(_) => true,
LIT_STR(_) => true,
LIT_STR_RAW(_, _) => true,
LIT_BINARY(_) => true,
match *t {
LIT_BYTE(_) => true,
LIT_CHAR(_) => true,
- LIT_INT(_, _) => true,
- LIT_UINT(_, _) => true,
- LIT_INT_UNSUFFIXED(_) => true,
- LIT_FLOAT(_, _) => true,
- LIT_FLOAT_UNSUFFIXED(_) => true,
+ LIT_INTEGER(_) => true,
+ LIT_FLOAT(_) => true,
LIT_STR(_) => true,
LIT_STR_RAW(_, _) => true,
LIT_BINARY(_) => true,
match *t { IDENT(_, false) => true, _ => false }
}
-pub fn is_bar(t: &Token) -> bool {
- match *t { BINOP(OR) | OROR => true, _ => false }
-}
-
// Get the first "argument"
macro_rules! first {
( $first:expr, $( $remainder:expr, )* ) => ( $first )
$( ($rk_name:expr, $rk_variant:ident, $rk_str:expr); )*
}
) => {
- static STRICT_KEYWORD_START: Name = first!($( $sk_name, )*);
- static STRICT_KEYWORD_FINAL: Name = last!($( $sk_name, )*);
- static RESERVED_KEYWORD_START: Name = first!($( $rk_name, )*);
- static RESERVED_KEYWORD_FINAL: Name = last!($( $rk_name, )*);
+ static STRICT_KEYWORD_START: Name = first!($( Name($sk_name), )*);
+ static STRICT_KEYWORD_FINAL: Name = last!($( Name($sk_name), )*);
+ static RESERVED_KEYWORD_START: Name = first!($( Name($rk_name), )*);
+ static RESERVED_KEYWORD_FINAL: Name = last!($( Name($rk_name), )*);
pub mod special_idents {
- use ast::Ident;
- $( pub static $si_static: Ident = Ident { name: $si_name, ctxt: 0 }; )*
+ use ast::{Ident, Name};
+ $( pub static $si_static: Ident = Ident { name: Name($si_name), ctxt: 0 }; )*
+ }
+
+ pub mod special_names {
+ use ast::Name;
+ $( pub static $si_static: Name = Name($si_name); )*
}
/**
* the language and may not appear as identifiers.
*/
pub mod keywords {
- use ast::Ident;
+ use ast::Name;
pub enum Keyword {
$( $sk_variant, )*
}
impl Keyword {
- pub fn to_ident(&self) -> Ident {
+ pub fn to_name(&self) -> Name {
match *self {
- $( $sk_variant => Ident { name: $sk_name, ctxt: 0 }, )*
- $( $rk_variant => Ident { name: $rk_name, ctxt: 0 }, )*
+ $( $sk_variant => Name($sk_name), )*
+ $( $rk_variant => Name($rk_name), )*
}
}
}
fn mk_fresh_ident_interner() -> IdentInterner {
// The indices here must correspond to the numbers in
- // special_idents, in Keyword to_ident(), and in static
+ // special_idents, in Keyword to_name(), and in static
// constants below.
let mut init_vec = Vec::new();
$(init_vec.push($si_str);)*
}}
// If the special idents get renumbered, remember to modify these two as appropriate
-static SELF_KEYWORD_NAME: Name = 1;
-static STATIC_KEYWORD_NAME: Name = 2;
+pub static SELF_KEYWORD_NAME: Name = Name(SELF_KEYWORD_NAME_NUM);
+static STATIC_KEYWORD_NAME: Name = Name(STATIC_KEYWORD_NAME_NUM);
+
+pub static SELF_KEYWORD_NAME_NUM: u32 = 1;
+static STATIC_KEYWORD_NAME_NUM: u32 = 2;
// NB: leaving holes in the ident table is bad! a different ident will get
// interned with the id from the hole, but it will be between the min and max
pub mod special_idents {
// These ones are statics
(0, invalid, "");
- (super::SELF_KEYWORD_NAME, self_, "self");
- (super::STATIC_KEYWORD_NAME, statik, "static");
+ (super::SELF_KEYWORD_NAME_NUM, self_, "self");
+ (super::STATIC_KEYWORD_NAME_NUM, statik, "static");
(3, static_lifetime, "'static");
// for matcher NTs
(29, Ref, "ref");
(30, Return, "return");
// Static and Self are also special idents (prefill de-dupes)
- (super::STATIC_KEYWORD_NAME, Static, "static");
- (super::SELF_KEYWORD_NAME, Self, "self");
+ (super::STATIC_KEYWORD_NAME_NUM, Static, "static");
+ (super::SELF_KEYWORD_NAME_NUM, Self, "self");
(31, Struct, "struct");
(32, Super, "super");
(33, True, "true");
/// Maps a string to an identifier with an empty syntax context.
#[inline]
-pub fn str_to_ident(s: &str) -> ast::Ident {
- ast::Ident::new(intern(s))
+pub fn str_to_ident(s: &str) -> Ident {
+ Ident::new(intern(s))
}
/// Maps a string to a gensym'ed identifier.
#[inline]
-pub fn gensym_ident(s: &str) -> ast::Ident {
- ast::Ident::new(gensym(s))
+pub fn gensym_ident(s: &str) -> Ident {
+ Ident::new(gensym(s))
}
// create a fresh name that maps to the same string as the old one.
-// note that this guarantees that str_ptr_eq(ident_to_str(src),interner_get(fresh_name(src)));
+// note that this guarantees that str_ptr_eq(ident_to_string(src),interner_get(fresh_name(src)));
// that is, that the new name and the old one are connected to ptr_eq strings.
-pub fn fresh_name(src: &ast::Ident) -> Name {
+pub fn fresh_name(src: &Ident) -> Name {
let interner = get_ident_interner();
interner.gensym_copy(src.name)
// following: debug version. Could work in final except that it's incompatible with
// good error messages and uses of struct names in ambiguous could-be-binding
// locations. Also definitely destroys the guarantee given above about ptr_eq.
/*let num = rand::task_rng().gen_uint_range(0,0xffff);
- gensym(format!("{}_{}",ident_to_str(src),num))*/
+ gensym(format!("{}_{}",ident_to_string(src),num))*/
}
// create a fresh mark.
pub fn fresh_mark() -> Mrk {
- gensym("mark")
+ gensym("mark").uint() as u32
}
// See the macro above about the types of keywords
pub fn is_keyword(kw: keywords::Keyword, tok: &Token) -> bool {
match *tok {
- token::IDENT(sid, false) => { kw.to_ident().name == sid.name }
+ token::IDENT(sid, false) => { kw.to_name() == sid.name }
_ => { false }
}
}
pub fn is_any_keyword(tok: &Token) -> bool {
match *tok {
- token::IDENT(sid, false) => match sid.name {
- SELF_KEYWORD_NAME | STATIC_KEYWORD_NAME |
- STRICT_KEYWORD_START .. RESERVED_KEYWORD_FINAL => true,
- _ => false,
+ token::IDENT(sid, false) => {
+ let n = sid.name;
+
+ n == SELF_KEYWORD_NAME
+ || n == STATIC_KEYWORD_NAME
+ || STRICT_KEYWORD_START <= n
+ && n <= RESERVED_KEYWORD_FINAL
},
_ => false
}
pub fn is_strict_keyword(tok: &Token) -> bool {
match *tok {
- token::IDENT(sid, false) => match sid.name {
- SELF_KEYWORD_NAME | STATIC_KEYWORD_NAME |
- STRICT_KEYWORD_START .. STRICT_KEYWORD_FINAL => true,
- _ => false,
+ token::IDENT(sid, false) => {
+ let n = sid.name;
+
+ n == SELF_KEYWORD_NAME
+ || n == STATIC_KEYWORD_NAME
+ || STRICT_KEYWORD_START <= n
+ && n <= STRICT_KEYWORD_FINAL
},
_ => false,
}
pub fn is_reserved_keyword(tok: &Token) -> bool {
match *tok {
- token::IDENT(sid, false) => match sid.name {
- RESERVED_KEYWORD_START .. RESERVED_KEYWORD_FINAL => true,
- _ => false,
+ token::IDENT(sid, false) => {
+ let n = sid.name;
+
+ RESERVED_KEYWORD_START <= n
+ && n <= RESERVED_KEYWORD_FINAL
},
_ => false,
}
use ext::mtwt;
fn mark_ident(id : ast::Ident, m : ast::Mrk) -> ast::Ident {
- ast::Ident{name:id.name,ctxt:mtwt::new_mark(m,id.ctxt)}
+ ast::Ident { name: id.name, ctxt:mtwt::apply_mark(m, id.ctxt) }
}
#[test] fn mtwt_token_eq_test() {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-/*
- * This pretty-printer is a direct reimplementation of Philip Karlton's
- * Mesa pretty-printer, as described in appendix A of
- *
- * STAN-CS-79-770: "Pretty Printing", by Derek C. Oppen.
- * Stanford Department of Computer Science, 1979.
- *
- * The algorithm's aim is to break a stream into as few lines as possible
- * while respecting the indentation-consistency requirements of the enclosing
- * block, and avoiding breaking at silly places on block boundaries, for
- * example, between "x" and ")" in "x)".
- *
- * I am implementing this algorithm because it comes with 20 pages of
- * documentation explaining its theory, and because it addresses the set of
- * concerns I've seen other pretty-printers fall down on. Weirdly. Even though
- * it's 32 years old. What can I say?
- *
- * Despite some redundancies and quirks in the way it's implemented in that
- * paper, I've opted to keep the implementation here as similar as I can,
- * changing only what was blatantly wrong, a typo, or sufficiently
- * non-idiomatic rust that it really stuck out.
- *
- * In particular you'll see a certain amount of churn related to INTEGER vs.
- * CARDINAL in the Mesa implementation. Mesa apparently interconverts the two
- * somewhat readily? In any case, I've used uint for indices-in-buffers and
- * ints for character-sizes-and-indentation-offsets. This respects the need
- * for ints to "go negative" while carrying a pending-calculation balance, and
- * helps differentiate all the numbers flying around internally (slightly).
- *
- * I also inverted the indentation arithmetic used in the print stack, since
- * the Mesa implementation (somewhat randomly) stores the offset on the print
- * stack in terms of margin-col rather than col itself. I store col.
- *
- * I also implemented a small change in the String token, in that I store an
- * explicit length for the string. For most tokens this is just the length of
- * the accompanying string. But it's necessary to permit it to differ, for
- * encoding things that are supposed to "go on their own line" -- certain
- * classes of comment and blank-line -- where relying on adjacent
- * hardbreak-like Break tokens with long blankness indication doesn't actually
- * work. To see why, consider when there is a "thing that should be on its own
- * line" between two long blocks, say functions. If you put a hardbreak after
- * each function (or before each) and the breaking algorithm decides to break
- * there anyways (because the functions themselves are long) you wind up with
- * extra blank lines. If you don't put hardbreaks you can wind up with the
- * "thing which should be on its own line" not getting its own line in the
- * rare case of "really small functions" or such. This re-occurs with comments
- * and explicit blank lines. So in those cases we use a string with a payload
- * we want isolated to a line and an explicit length that's huge, surrounded
- * by two zero-length breaks. The algorithm will try its best to fit it on a
- * line (which it can't) and so naturally place the content on its own line to
- * avoid combining it with other lines and making matters even worse.
- */
+//! This pretty-printer is a direct reimplementation of Philip Karlton's
+//! Mesa pretty-printer, as described in appendix A of
+//!
+//! STAN-CS-79-770: "Pretty Printing", by Derek C. Oppen.
+//! Stanford Department of Computer Science, 1979.
+//!
+//! The algorithm's aim is to break a stream into as few lines as possible
+//! while respecting the indentation-consistency requirements of the enclosing
+//! block, and avoiding breaking at silly places on block boundaries, for
+//! example, between "x" and ")" in "x)".
+//!
+//! I am implementing this algorithm because it comes with 20 pages of
+//! documentation explaining its theory, and because it addresses the set of
+//! concerns I've seen other pretty-printers fall down on. Weirdly. Even though
+//! it's 32 years old. What can I say?
+//!
+//! Despite some redundancies and quirks in the way it's implemented in that
+//! paper, I've opted to keep the implementation here as similar as I can,
+//! changing only what was blatantly wrong, a typo, or sufficiently
+//! non-idiomatic rust that it really stuck out.
+//!
+//! In particular you'll see a certain amount of churn related to INTEGER vs.
+//! CARDINAL in the Mesa implementation. Mesa apparently interconverts the two
+//! somewhat readily? In any case, I've used uint for indices-in-buffers and
+//! ints for character-sizes-and-indentation-offsets. This respects the need
+//! for ints to "go negative" while carrying a pending-calculation balance, and
+//! helps differentiate all the numbers flying around internally (slightly).
+//!
+//! I also inverted the indentation arithmetic used in the print stack, since
+//! the Mesa implementation (somewhat randomly) stores the offset on the print
+//! stack in terms of margin-col rather than col itself. I store col.
+//!
+//! I also implemented a small change in the String token, in that I store an
+//! explicit length for the string. For most tokens this is just the length of
+//! the accompanying string. But it's necessary to permit it to differ, for
+//! encoding things that are supposed to "go on their own line" -- certain
+//! classes of comment and blank-line -- where relying on adjacent
+//! hardbreak-like Break tokens with long blankness indication doesn't actually
+//! work. To see why, consider when there is a "thing that should be on its own
+//! line" between two long blocks, say functions. If you put a hardbreak after
+//! each function (or before each) and the breaking algorithm decides to break
+//! there anyways (because the functions themselves are long) you wind up with
+//! extra blank lines. If you don't put hardbreaks you can wind up with the
+//! "thing which should be on its own line" not getting its own line in the
+//! rare case of "really small functions" or such. This re-occurs with comments
+//! and explicit blank lines. So in those cases we use a string with a payload
+//! we want isolated to a line and an explicit length that's huge, surrounded
+//! by two zero-length breaks. The algorithm will try its best to fit it on a
+//! line (which it can't) and so naturally place the content on its own line to
+//! avoid combining it with other lines and making matters even worse.
use std::io;
use std::string::String;
}
-/*
- * In case you do not have the paper, here is an explanation of what's going
- * on.
- *
- * There is a stream of input tokens flowing through this printer.
- *
- * The printer buffers up to 3N tokens inside itself, where N is linewidth.
- * Yes, linewidth is chars and tokens are multi-char, but in the worst
- * case every token worth buffering is 1 char long, so it's ok.
- *
- * Tokens are String, Break, and Begin/End to delimit blocks.
- *
- * Begin tokens can carry an offset, saying "how far to indent when you break
- * inside here", as well as a flag indicating "consistent" or "inconsistent"
- * breaking. Consistent breaking means that after the first break, no attempt
- * will be made to flow subsequent breaks together onto lines. Inconsistent
- * is the opposite. Inconsistent breaking example would be, say:
- *
- * foo(hello, there, good, friends)
- *
- * breaking inconsistently to become
- *
- * foo(hello, there
- * good, friends);
- *
- * whereas a consistent breaking would yield:
- *
- * foo(hello,
- * there
- * good,
- * friends);
- *
- * That is, in the consistent-break blocks we value vertical alignment
- * more than the ability to cram stuff onto a line. But in all cases if it
- * can make a block a one-liner, it'll do so.
- *
- * Carrying on with high-level logic:
- *
- * The buffered tokens go through a ring-buffer, 'tokens'. The 'left' and
- * 'right' indices denote the active portion of the ring buffer as well as
- * describing hypothetical points-in-the-infinite-stream at most 3N tokens
- * apart (i.e. "not wrapped to ring-buffer boundaries"). The paper will switch
- * between using 'left' and 'right' terms to denote the wrapepd-to-ring-buffer
- * and point-in-infinite-stream senses freely.
- *
- * There is a parallel ring buffer, 'size', that holds the calculated size of
- * each token. Why calculated? Because for Begin/End pairs, the "size"
- * includes everything between the pair. That is, the "size" of Begin is
- * actually the sum of the sizes of everything between Begin and the paired
- * End that follows. Since that is arbitrarily far in the future, 'size' is
- * being rewritten regularly while the printer runs; in fact most of the
- * machinery is here to work out 'size' entries on the fly (and give up when
- * they're so obviously over-long that "infinity" is a good enough
- * approximation for purposes of line breaking).
- *
- * The "input side" of the printer is managed as an abstract process called
- * SCAN, which uses 'scan_stack', 'scan_stack_empty', 'top' and 'bottom', to
- * manage calculating 'size'. SCAN is, in other words, the process of
- * calculating 'size' entries.
- *
- * The "output side" of the printer is managed by an abstract process called
- * PRINT, which uses 'print_stack', 'margin' and 'space' to figure out what to
- * do with each token/size pair it consumes as it goes. It's trying to consume
- * the entire buffered window, but can't output anything until the size is >=
- * 0 (sizes are set to negative while they're pending calculation).
- *
- * So SCAN takes input and buffers tokens and pending calculations, while
- * PRINT gobbles up completed calculations and tokens from the buffer. The
- * theory is that the two can never get more than 3N tokens apart, because
- * once there's "obviously" too much data to fit on a line, in a size
- * calculation, SCAN will write "infinity" to the size and let PRINT consume
- * it.
- *
- * In this implementation (following the paper, again) the SCAN process is
- * the method called 'pretty_print', and the 'PRINT' process is the method
- * called 'print'.
- */
+/// In case you do not have the paper, here is an explanation of what's going
+/// on.
+///
+/// There is a stream of input tokens flowing through this printer.
+///
+/// The printer buffers up to 3N tokens inside itself, where N is linewidth.
+/// Yes, linewidth is chars and tokens are multi-char, but in the worst
+/// case every token worth buffering is 1 char long, so it's ok.
+///
+/// Tokens are String, Break, and Begin/End to delimit blocks.
+///
+/// Begin tokens can carry an offset, saying "how far to indent when you break
+/// inside here", as well as a flag indicating "consistent" or "inconsistent"
+/// breaking. Consistent breaking means that after the first break, no attempt
+/// will be made to flow subsequent breaks together onto lines. Inconsistent
+/// is the opposite. Inconsistent breaking example would be, say:
+///
+/// foo(hello, there, good, friends)
+///
+/// breaking inconsistently to become
+///
+/// foo(hello, there
+/// good, friends);
+///
+/// whereas a consistent breaking would yield:
+///
+/// foo(hello,
+/// there
+/// good,
+/// friends);
+///
+/// That is, in the consistent-break blocks we value vertical alignment
+/// more than the ability to cram stuff onto a line. But in all cases if it
+/// can make a block a one-liner, it'll do so.
+///
+/// Carrying on with high-level logic:
+///
+/// The buffered tokens go through a ring-buffer, 'tokens'. The 'left' and
+/// 'right' indices denote the active portion of the ring buffer as well as
+/// describing hypothetical points-in-the-infinite-stream at most 3N tokens
+/// apart (i.e. "not wrapped to ring-buffer boundaries"). The paper will switch
+/// between using 'left' and 'right' terms to denote the wrapepd-to-ring-buffer
+/// and point-in-infinite-stream senses freely.
+///
+/// There is a parallel ring buffer, 'size', that holds the calculated size of
+/// each token. Why calculated? Because for Begin/End pairs, the "size"
+/// includes everything betwen the pair. That is, the "size" of Begin is
+/// actually the sum of the sizes of everything between Begin and the paired
+/// End that follows. Since that is arbitrarily far in the future, 'size' is
+/// being rewritten regularly while the printer runs; in fact most of the
+/// machinery is here to work out 'size' entries on the fly (and give up when
+/// they're so obviously over-long that "infinity" is a good enough
+/// approximation for purposes of line breaking).
+///
+/// The "input side" of the printer is managed as an abstract process called
+/// SCAN, which uses 'scan_stack', 'scan_stack_empty', 'top' and 'bottom', to
+/// manage calculating 'size'. SCAN is, in other words, the process of
+/// calculating 'size' entries.
+///
+/// The "output side" of the printer is managed by an abstract process called
+/// PRINT, which uses 'print_stack', 'margin' and 'space' to figure out what to
+/// do with each token/size pair it consumes as it goes. It's trying to consume
+/// the entire buffered window, but can't output anything until the size is >=
+/// 0 (sizes are set to negative while they're pending calculation).
+///
+/// So SCAN takes input and buffers tokens and pending calculations, while
+/// PRINT gobbles up completed calculations and tokens from the buffer. The
+/// theory is that the two can never get more than 3N tokens apart, because
+/// once there's "obviously" too much data to fit on a line, in a size
+/// calculation, SCAN will write "infinity" to the size and let PRINT consume
+/// it.
+///
+/// In this implementation (following the paper, again) the SCAN process is
+/// the method called 'pretty_print', and the 'PRINT' process is the method
+/// called 'print'.
pub struct Printer {
pub out: Box<io::Writer>,
buf_len: uint,
- margin: int, // width of lines we're constrained to
- space: int, // number of spaces left on line
- left: uint, // index of left side of input stream
- right: uint, // index of right side of input stream
- token: Vec<Token> , // ring-buffr stream goes through
- size: Vec<int> , // ring-buffer of calculated sizes
- left_total: int, // running size of stream "...left"
- right_total: int, // running size of stream "...right"
- // pseudo-stack, really a ring too. Holds the
- // primary-ring-buffers index of the Begin that started the
- // current block, possibly with the most recent Break after that
- // Begin (if there is any) on top of it. Stuff is flushed off the
- // bottom as it becomes irrelevant due to the primary ring-buffer
- // advancing.
+ /// Width of lines we're constrained to
+ margin: int,
+ /// Number of spaces left on line
+ space: int,
+ /// Index of left side of input stream
+ left: uint,
+ /// Index of right side of input stream
+ right: uint,
+ /// Ring-buffr stream goes through
+ token: Vec<Token> ,
+ /// Ring-buffer of calculated sizes
+ size: Vec<int> ,
+ /// Running size of stream "...left"
+ left_total: int,
+ /// Running size of stream "...right"
+ right_total: int,
+ /// Pseudo-stack, really a ring too. Holds the
+ /// primary-ring-buffers index of the Begin that started the
+ /// current block, possibly with the most recent Break after that
+ /// Begin (if there is any) on top of it. Stuff is flushed off the
+ /// bottom as it becomes irrelevant due to the primary ring-buffer
+ /// advancing.
scan_stack: Vec<uint> ,
- scan_stack_empty: bool, // top==bottom disambiguator
- top: uint, // index of top of scan_stack
- bottom: uint, // index of bottom of scan_stack
- // stack of blocks-in-progress being flushed by print
+ /// Top==bottom disambiguator
+ scan_stack_empty: bool,
+ /// Index of top of scan_stack
+ top: uint,
+ /// Index of bottom of scan_stack
+ bottom: uint,
+ /// Stack of blocks-in-progress being flushed by print
print_stack: Vec<PrintStackElem> ,
- // buffered indentation to avoid writing trailing whitespace
+ /// Buffered indentation to avoid writing trailing whitespace
pending_indentation: int,
}
pub static default_columns: uint = 78u;
-// Requires you to pass an input filename and reader so that
-// it can scan the input text for comments and literals to
-// copy forward.
+/// Requires you to pass an input filename and reader so that
+/// it can scan the input text for comments and literals to
+/// copy forward.
pub fn print_crate<'a>(cm: &'a CodeMap,
span_diagnostic: &diagnostic::SpanHandler,
krate: &ast::Crate,
eof(&mut s.s)
}
-pub fn to_str(f: |&mut State| -> IoResult<()>) -> String {
+pub fn to_string(f: |&mut State| -> IoResult<()>) -> String {
let mut s = rust_printer(box MemWriter::new());
f(&mut s).unwrap();
eof(&mut s.s).unwrap();
}
}
-pub fn ty_to_str(ty: &ast::Ty) -> String {
- to_str(|s| s.print_type(ty))
+pub fn ty_to_string(ty: &ast::Ty) -> String {
+ to_string(|s| s.print_type(ty))
}
-pub fn pat_to_str(pat: &ast::Pat) -> String {
- to_str(|s| s.print_pat(pat))
+pub fn pat_to_string(pat: &ast::Pat) -> String {
+ to_string(|s| s.print_pat(pat))
}
-pub fn expr_to_str(e: &ast::Expr) -> String {
- to_str(|s| s.print_expr(e))
+pub fn expr_to_string(e: &ast::Expr) -> String {
+ to_string(|s| s.print_expr(e))
}
-pub fn lifetime_to_str(e: &ast::Lifetime) -> String {
- to_str(|s| s.print_lifetime(e))
+pub fn lifetime_to_string(e: &ast::Lifetime) -> String {
+ to_string(|s| s.print_lifetime(e))
}
-pub fn tt_to_str(tt: &ast::TokenTree) -> String {
- to_str(|s| s.print_tt(tt))
+pub fn tt_to_string(tt: &ast::TokenTree) -> String {
+ to_string(|s| s.print_tt(tt))
}
-pub fn tts_to_str(tts: &[ast::TokenTree]) -> String {
- to_str(|s| s.print_tts(tts))
+pub fn tts_to_string(tts: &[ast::TokenTree]) -> String {
+ to_string(|s| s.print_tts(tts))
}
-pub fn stmt_to_str(stmt: &ast::Stmt) -> String {
- to_str(|s| s.print_stmt(stmt))
+pub fn stmt_to_string(stmt: &ast::Stmt) -> String {
+ to_string(|s| s.print_stmt(stmt))
}
-pub fn item_to_str(i: &ast::Item) -> String {
- to_str(|s| s.print_item(i))
+pub fn item_to_string(i: &ast::Item) -> String {
+ to_string(|s| s.print_item(i))
}
-pub fn generics_to_str(generics: &ast::Generics) -> String {
- to_str(|s| s.print_generics(generics))
+pub fn generics_to_string(generics: &ast::Generics) -> String {
+ to_string(|s| s.print_generics(generics))
}
-pub fn ty_method_to_str(p: &ast::TypeMethod) -> String {
- to_str(|s| s.print_ty_method(p))
+pub fn ty_method_to_string(p: &ast::TypeMethod) -> String {
+ to_string(|s| s.print_ty_method(p))
}
-pub fn method_to_str(p: &ast::Method) -> String {
- to_str(|s| s.print_method(p))
+pub fn method_to_string(p: &ast::Method) -> String {
+ to_string(|s| s.print_method(p))
}
-pub fn fn_block_to_str(p: &ast::FnDecl) -> String {
- to_str(|s| s.print_fn_block_args(p))
+pub fn fn_block_to_string(p: &ast::FnDecl) -> String {
+ to_string(|s| s.print_fn_block_args(p))
}
-pub fn path_to_str(p: &ast::Path) -> String {
- to_str(|s| s.print_path(p, false))
+pub fn path_to_string(p: &ast::Path) -> String {
+ to_string(|s| s.print_path(p, false))
}
-pub fn ident_to_str(id: &ast::Ident) -> String {
- to_str(|s| s.print_ident(*id))
+pub fn ident_to_string(id: &ast::Ident) -> String {
+ to_string(|s| s.print_ident(*id))
}
-pub fn fun_to_str(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident,
+pub fn fun_to_string(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident,
opt_explicit_self: Option<ast::ExplicitSelf_>,
generics: &ast::Generics) -> String {
- to_str(|s| {
+ to_string(|s| {
try!(s.print_fn(decl, Some(fn_style), abi::Rust,
name, generics, opt_explicit_self, ast::Inherited));
try!(s.end()); // Close the head box
})
}
-pub fn block_to_str(blk: &ast::Block) -> String {
- to_str(|s| {
+pub fn block_to_string(blk: &ast::Block) -> String {
+ to_string(|s| {
// containing cbox, will be closed by print-block at }
try!(s.cbox(indent_unit));
// head-ibox, will be closed by print-block after {
})
}
-pub fn meta_item_to_str(mi: &ast::MetaItem) -> String {
- to_str(|s| s.print_meta_item(mi))
+pub fn meta_item_to_string(mi: &ast::MetaItem) -> String {
+ to_string(|s| s.print_meta_item(mi))
}
-pub fn attribute_to_str(attr: &ast::Attribute) -> String {
- to_str(|s| s.print_attribute(attr))
+pub fn attribute_to_string(attr: &ast::Attribute) -> String {
+ to_string(|s| s.print_attribute(attr))
}
-pub fn lit_to_str(l: &ast::Lit) -> String {
- to_str(|s| s.print_literal(l))
+pub fn lit_to_string(l: &ast::Lit) -> String {
+ to_string(|s| s.print_literal(l))
}
-pub fn explicit_self_to_str(explicit_self: ast::ExplicitSelf_) -> String {
- to_str(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
+pub fn explicit_self_to_string(explicit_self: ast::ExplicitSelf_) -> String {
+ to_string(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
}
-pub fn variant_to_str(var: &ast::Variant) -> String {
- to_str(|s| s.print_variant(var))
+pub fn variant_to_string(var: &ast::Variant) -> String {
+ to_string(|s| s.print_variant(var))
}
-pub fn arg_to_str(arg: &ast::Arg) -> String {
- to_str(|s| s.print_arg(arg))
+pub fn arg_to_string(arg: &ast::Arg) -> String {
+ to_string(|s| s.print_arg(arg))
+}
+
+pub fn mac_to_string(arg: &ast::Mac) -> String {
+ to_string(|s| s.print_mac(arg))
}
pub fn visibility_qualified(vis: ast::Visibility, s: &str) -> String {
match self.s.last_token() { pp::End => true, _ => false }
}
+ // is this the beginning of a line?
pub fn is_bol(&mut self) -> bool {
self.s.last_token().is_eof() || self.s.last_token().is_hardbreak_tok()
}
}
}
+ /// Pretty-print an item
pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
try!(self.hardbreak_if_not_bol());
try!(self.maybe_print_comment(item.span.lo));
}
ast::ItemForeignMod(ref nmod) => {
try!(self.head("extern"));
- try!(self.word_nbsp(nmod.abi.to_str().as_slice()));
+ try!(self.word_nbsp(nmod.abi.to_string().as_slice()));
try!(self.bopen());
try!(self.print_foreign_mod(nmod, item.attrs.as_slice()));
try!(self.bclose(item.span));
}
try!(self.bclose(item.span));
}
- ast::ItemTrait(ref generics, ref sized, ref traits, ref methods) => {
+ ast::ItemTrait(ref generics, ref unbound, ref traits, ref methods) => {
try!(self.head(visibility_qualified(item.vis,
"trait").as_slice()));
try!(self.print_ident(item.ident));
try!(self.print_generics(generics));
- if *sized == ast::DynSize {
- try!(space(&mut self.s));
- try!(word(&mut self.s, "for type"));
+ match unbound {
+ &Some(TraitTyParamBound(ref tref)) => {
+ try!(space(&mut self.s));
+ try!(self.word_space("for"));
+ try!(self.print_trait_ref(tref));
+ try!(word(&mut self.s, "?"));
+ }
+ _ => {}
}
if traits.len() != 0u {
try!(word(&mut self.s, ":"));
match *tt {
ast::TTDelim(ref tts) => self.print_tts(tts.as_slice()),
ast::TTTok(_, ref tk) => {
- try!(word(&mut self.s, parse::token::to_str(tk).as_slice()));
+ try!(word(&mut self.s, parse::token::to_string(tk).as_slice()));
match *tk {
parse::token::DOC_COMMENT(..) => {
hardbreak(&mut self.s)
match *sep {
Some(ref tk) => {
try!(word(&mut self.s,
- parse::token::to_str(tk).as_slice()));
+ parse::token::to_string(tk).as_slice()));
}
None => ()
}
try!(self.hardbreak_if_not_bol());
try!(self.maybe_print_comment(meth.span.lo));
try!(self.print_outer_attributes(meth.attrs.as_slice()));
- try!(self.print_fn(&*meth.decl, Some(meth.fn_style), abi::Rust,
- meth.ident, &meth.generics, Some(meth.explicit_self.node),
- meth.vis));
- try!(word(&mut self.s, " "));
- self.print_block_with_attrs(&*meth.body, meth.attrs.as_slice())
+ match meth.node {
+ ast::MethDecl(ident, ref generics, ref explicit_self, fn_style, decl, body, vis) => {
+ try!(self.print_fn(&*decl, Some(fn_style), abi::Rust,
+ ident, generics, Some(explicit_self.node),
+ vis));
+ try!(word(&mut self.s, " "));
+ self.print_block_with_attrs(&*body, meth.attrs.as_slice())
+ },
+ ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
+ ..}) => {
+ // code copied from ItemMac:
+ try!(self.print_path(pth, false));
+ try!(word(&mut self.s, "! "));
+ try!(self.cbox(indent_unit));
+ try!(self.popen());
+ try!(self.print_tts(tts.as_slice()));
+ try!(self.pclose());
+ self.end()
+ }
+ }
}
pub fn print_outer_attributes(&mut self,
ast::ExprBinary(op, ref lhs, ref rhs) => {
try!(self.print_expr(&**lhs));
try!(space(&mut self.s));
- try!(self.word_space(ast_util::binop_to_str(op)));
+ try!(self.word_space(ast_util::binop_to_string(op)));
try!(self.print_expr(&**rhs));
}
ast::ExprUnary(op, ref expr) => {
- try!(word(&mut self.s, ast_util::unop_to_str(op)));
+ try!(word(&mut self.s, ast_util::unop_to_string(op)));
try!(self.print_expr_maybe_paren(&**expr));
}
ast::ExprAddrOf(m, ref expr) => {
ast::ExprAssignOp(op, ref lhs, ref rhs) => {
try!(self.print_expr(&**lhs));
try!(space(&mut self.s));
- try!(word(&mut self.s, ast_util::binop_to_str(op)));
+ try!(word(&mut self.s, ast_util::binop_to_string(op)));
try!(self.word_space("="));
try!(self.print_expr(&**rhs));
}
}
ast::PatStruct(ref path, ref fields, etc) => {
try!(self.print_path(path, true));
- try!(word(&mut self.s, "{"));
+ try!(self.nbsp());
+ try!(self.word_space("{"));
try!(self.commasep_cmnt(
Consistent, fields.as_slice(),
|s, f| {
try!(s.cbox(indent_unit));
try!(s.print_ident(f.ident));
- try!(s.word_space(":"));
+ try!(s.word_nbsp(":"));
try!(s.print_pat(&*f.pat));
s.end()
},
if fields.len() != 0u { try!(self.word_space(",")); }
try!(word(&mut self.s, ".."));
}
+ try!(space(&mut self.s));
try!(word(&mut self.s, "}"));
}
ast::PatTup(ref elts) => {
try!(self.print_mutability(mutbl));
match explicit_self {
ast::SelfStatic => { return Ok(false); }
- ast::SelfValue => {
+ ast::SelfValue(_) => {
try!(word(&mut self.s, "self"));
}
- ast::SelfUniq => {
+ ast::SelfUniq(_) => {
try!(word(&mut self.s, "~self"));
}
- ast::SelfRegion(ref lt, m) => {
+ ast::SelfRegion(ref lt, m, _) => {
try!(word(&mut self.s, "&"));
try!(self.print_opt_lifetime(lt));
try!(self.print_mutability(m));
} else {
let idx = idx - generics.lifetimes.len();
let param = generics.ty_params.get(idx);
- if param.sized == ast::DynSize {
- try!(s.word_space("type"));
+ match param.unbound {
+ Some(TraitTyParamBound(ref tref)) => {
+ try!(s.print_trait_ref(tref));
+ try!(s.word_space("?"));
+ }
+ _ => {}
}
try!(s.print_ident(param.ident));
try!(s.print_bounds(&None,
}
ast::LitInt(i, t) => {
word(&mut self.s,
- ast_util::int_ty_to_str(t, Some(i)).as_slice())
+ ast_util::int_ty_to_string(t, Some(i)).as_slice())
}
ast::LitUint(u, t) => {
word(&mut self.s,
- ast_util::uint_ty_to_str(t, Some(u)).as_slice())
+ ast_util::uint_ty_to_string(t, Some(u)).as_slice())
}
ast::LitIntUnsuffixed(i) => {
word(&mut self.s, format!("{}", i).as_slice())
format!(
"{}{}",
f.get(),
- ast_util::float_ty_to_str(t).as_slice()).as_slice())
+ ast_util::float_ty_to_string(t).as_slice()).as_slice())
}
ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, f.get()),
ast::LitNil => word(&mut self.s, "()"),
Some(abi::Rust) => Ok(()),
Some(abi) => {
try!(self.word_nbsp("extern"));
- self.word_nbsp(abi.to_str().as_slice())
+ self.word_nbsp(abi.to_string().as_slice())
}
None => Ok(())
}
match opt_abi {
Some(abi) => {
try!(self.word_nbsp("extern"));
- self.word_nbsp(abi.to_str().as_slice())
+ self.word_nbsp(abi.to_string().as_slice())
}
None => Ok(())
}
if abi != abi::Rust {
try!(self.word_nbsp("extern"));
- try!(self.word_nbsp(abi.to_str().as_slice()));
+ try!(self.word_nbsp(abi.to_string().as_slice()));
}
word(&mut self.s, "fn")
use parse::token;
#[test]
- fn test_fun_to_str() {
+ fn test_fun_to_string() {
let abba_ident = token::str_to_ident("abba");
let decl = ast::FnDecl {
variadic: false
};
let generics = ast_util::empty_generics();
- assert_eq!(&fun_to_str(&decl, ast::NormalFn, abba_ident,
+ assert_eq!(&fun_to_string(&decl, ast::NormalFn, abba_ident,
None, &generics),
&"fn abba()".to_string());
}
#[test]
- fn test_variant_to_str() {
+ fn test_variant_to_string() {
let ident = token::str_to_ident("principal_skinner");
let var = codemap::respan(codemap::DUMMY_SP, ast::Variant_ {
vis: ast::Public,
});
- let varstr = variant_to_str(&var);
+ let varstr = variant_to_string(&var);
assert_eq!(&varstr,&"pub principal_skinner".to_string());
}
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// An "interner" is a data structure that associates values with uint tags and
-// allows bidirectional lookup; i.e. given a value, one can easily find the
-// type, and vice versa.
+//! An "interner" is a data structure that associates values with uint tags and
+//! allows bidirectional lookup; i.e. given a value, one can easily find the
+//! type, and vice versa.
use ast::Name;
}
let mut vect = self.vect.borrow_mut();
- let new_idx = (*vect).len() as Name;
+ let new_idx = Name((*vect).len() as u32);
(*map).insert(val.clone(), new_idx);
(*vect).push(val);
new_idx
pub fn gensym(&self, val: T) -> Name {
let mut vect = self.vect.borrow_mut();
- let new_idx = (*vect).len() as Name;
+ let new_idx = Name((*vect).len() as u32);
// leave out of .map to avoid colliding
(*vect).push(val);
new_idx
pub fn get(&self, idx: Name) -> T {
let vect = self.vect.borrow();
- (*(*vect).get(idx as uint)).clone()
+ (*(*vect).get(idx.uint())).clone()
}
pub fn len(&self) -> uint {
None => (),
}
- let new_idx = self.len() as Name;
+ let new_idx = Name(self.len() as u32);
let val = RcStr::new(val);
map.insert(val.clone(), new_idx);
self.vect.borrow_mut().push(val);
}
pub fn gensym(&self, val: &str) -> Name {
- let new_idx = self.len() as Name;
+ let new_idx = Name(self.len() as u32);
// leave out of .map to avoid colliding
self.vect.borrow_mut().push(RcStr::new(val));
new_idx
/// Create a gensym with the same name as an existing
/// entry.
pub fn gensym_copy(&self, idx : Name) -> Name {
- let new_idx = self.len() as Name;
+ let new_idx = Name(self.len() as u32);
// leave out of map to avoid colliding
let mut vect = self.vect.borrow_mut();
- let existing = (*vect.get(idx as uint)).clone();
+ let existing = (*vect.get(idx.uint())).clone();
vect.push(existing);
new_idx
}
pub fn get(&self, idx: Name) -> RcStr {
- (*self.vect.borrow().get(idx as uint)).clone()
+ (*self.vect.borrow().get(idx.uint())).clone()
}
/// Returns this string with lifetime tied to the interner. Since
/// strings may never be removed from the interner, this is safe.
pub fn get_ref<'a>(&'a self, idx: Name) -> &'a str {
let vect = self.vect.borrow();
- let s: &str = vect.get(idx as uint).as_slice();
+ let s: &str = vect.get(idx.uint()).as_slice();
unsafe {
mem::transmute(s)
}
#[cfg(test)]
mod tests {
use super::*;
+ use ast::Name;
+
#[test]
#[should_fail]
fn i1 () {
let i : Interner<RcStr> = Interner::new();
- i.get(13);
+ i.get(Name(13));
}
#[test]
fn interner_tests () {
let i : Interner<RcStr> = Interner::new();
// first one is zero:
- assert_eq!(i.intern(RcStr::new("dog")), 0);
+ assert_eq!(i.intern(RcStr::new("dog")), Name(0));
// re-use gets the same entry:
- assert_eq!(i.intern(RcStr::new("dog")), 0);
+ assert_eq!(i.intern(RcStr::new("dog")), Name(0));
// different string gets a different #:
- assert_eq!(i.intern(RcStr::new("cat")), 1);
- assert_eq!(i.intern(RcStr::new("cat")), 1);
+ assert_eq!(i.intern(RcStr::new("cat")), Name(1));
+ assert_eq!(i.intern(RcStr::new("cat")), Name(1));
// dog is still at zero
- assert_eq!(i.intern(RcStr::new("dog")), 0);
+ assert_eq!(i.intern(RcStr::new("dog")), Name(0));
// gensym gets 3
- assert_eq!(i.gensym(RcStr::new("zebra") ), 2);
+ assert_eq!(i.gensym(RcStr::new("zebra") ), Name(2));
// gensym of same string gets new number :
- assert_eq!(i.gensym (RcStr::new("zebra") ), 3);
+ assert_eq!(i.gensym (RcStr::new("zebra") ), Name(3));
// gensym of *existing* string gets new number:
- assert_eq!(i.gensym(RcStr::new("dog")), 4);
- assert_eq!(i.get(0), RcStr::new("dog"));
- assert_eq!(i.get(1), RcStr::new("cat"));
- assert_eq!(i.get(2), RcStr::new("zebra"));
- assert_eq!(i.get(3), RcStr::new("zebra"));
- assert_eq!(i.get(4), RcStr::new("dog"));
+ assert_eq!(i.gensym(RcStr::new("dog")), Name(4));
+ assert_eq!(i.get(Name(0)), RcStr::new("dog"));
+ assert_eq!(i.get(Name(1)), RcStr::new("cat"));
+ assert_eq!(i.get(Name(2)), RcStr::new("zebra"));
+ assert_eq!(i.get(Name(3)), RcStr::new("zebra"));
+ assert_eq!(i.get(Name(4)), RcStr::new("dog"));
}
#[test]
RcStr::new("Bob"),
RcStr::new("Carol")
]);
- assert_eq!(i.get(0), RcStr::new("Alan"));
- assert_eq!(i.get(1), RcStr::new("Bob"));
- assert_eq!(i.get(2), RcStr::new("Carol"));
- assert_eq!(i.intern(RcStr::new("Bob")), 1);
+ assert_eq!(i.get(Name(0)), RcStr::new("Alan"));
+ assert_eq!(i.get(Name(1)), RcStr::new("Bob"));
+ assert_eq!(i.get(Name(2)), RcStr::new("Carol"));
+ assert_eq!(i.intern(RcStr::new("Bob")), Name(1));
}
#[test]
fn string_interner_tests() {
let i : StrInterner = StrInterner::new();
// first one is zero:
- assert_eq!(i.intern("dog"), 0);
+ assert_eq!(i.intern("dog"), Name(0));
// re-use gets the same entry:
- assert_eq!(i.intern ("dog"), 0);
+ assert_eq!(i.intern ("dog"), Name(0));
// different string gets a different #:
- assert_eq!(i.intern("cat"), 1);
- assert_eq!(i.intern("cat"), 1);
+ assert_eq!(i.intern("cat"), Name(1));
+ assert_eq!(i.intern("cat"), Name(1));
// dog is still at zero
- assert_eq!(i.intern("dog"), 0);
+ assert_eq!(i.intern("dog"), Name(0));
// gensym gets 3
- assert_eq!(i.gensym("zebra"), 2);
+ assert_eq!(i.gensym("zebra"), Name(2));
// gensym of same string gets new number :
- assert_eq!(i.gensym("zebra"), 3);
+ assert_eq!(i.gensym("zebra"), Name(3));
// gensym of *existing* string gets new number:
- assert_eq!(i.gensym("dog"), 4);
+ assert_eq!(i.gensym("dog"), Name(4));
// gensym tests again with gensym_copy:
- assert_eq!(i.gensym_copy(2), 5);
- assert_eq!(i.get(5), RcStr::new("zebra"));
- assert_eq!(i.gensym_copy(2), 6);
- assert_eq!(i.get(6), RcStr::new("zebra"));
- assert_eq!(i.get(0), RcStr::new("dog"));
- assert_eq!(i.get(1), RcStr::new("cat"));
- assert_eq!(i.get(2), RcStr::new("zebra"));
- assert_eq!(i.get(3), RcStr::new("zebra"));
- assert_eq!(i.get(4), RcStr::new("dog"));
+ assert_eq!(i.gensym_copy(Name(2)), Name(5));
+ assert_eq!(i.get(Name(5)), RcStr::new("zebra"));
+ assert_eq!(i.gensym_copy(Name(2)), Name(6));
+ assert_eq!(i.get(Name(6)), RcStr::new("zebra"));
+ assert_eq!(i.get(Name(0)), RcStr::new("dog"));
+ assert_eq!(i.get(Name(1)), RcStr::new("cat"));
+ assert_eq!(i.get(Name(2)), RcStr::new("zebra"));
+ assert_eq!(i.get(Name(3)), RcStr::new("zebra"));
+ assert_eq!(i.get(Name(4)), RcStr::new("dog"));
}
}
use std::gc::Gc;
-// map a string to tts, using a made-up filename:
+/// Map a string to tts, using a made-up filename:
pub fn string_to_tts(source_str: String) -> Vec<ast::TokenTree> {
let ps = new_parse_sess();
filemap_to_tts(&ps,
string_to_filemap(&ps, source_str, "bogofile".to_string()))
}
-// map string to parser (via tts)
+/// Map string to parser (via tts)
pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a> {
new_parser_from_source_str(ps,
Vec::new(),
x
}
-// parse a string, return a crate.
+/// Parse a string, return a crate.
pub fn string_to_crate (source_str : String) -> ast::Crate {
with_error_checking_parse(source_str, |p| {
p.parse_crate_mod()
})
}
-// parse a string, return an expr
+/// Parse a string, return an expr
pub fn string_to_expr (source_str : String) -> Gc<ast::Expr> {
with_error_checking_parse(source_str, |p| {
p.parse_expr()
})
}
-// parse a string, return an item
+/// Parse a string, return an item
pub fn string_to_item (source_str : String) -> Option<Gc<ast::Item>> {
with_error_checking_parse(source_str, |p| {
p.parse_item(Vec::new())
})
}
-// parse a string, return a stmt
+/// Parse a string, return a stmt
pub fn string_to_stmt(source_str : String) -> Gc<ast::Stmt> {
with_error_checking_parse(source_str, |p| {
p.parse_stmt(Vec::new())
})
}
-// parse a string, return a pat. Uses "irrefutable"... which doesn't
-// (currently) affect parsing.
+/// Parse a string, return a pat. Uses "irrefutable"... which doesn't
+/// (currently) affect parsing.
pub fn string_to_pat(source_str: String) -> Gc<ast::Pat> {
string_to_parser(&new_parse_sess(), source_str).parse_pat()
}
-// convert a vector of strings to a vector of ast::Ident's
+/// Convert a vector of strings to a vector of ast::Ident's
pub fn strs_to_idents(ids: Vec<&str> ) -> Vec<ast::Ident> {
ids.iter().map(|u| token::str_to_ident(*u)).collect()
}
-// does the given string match the pattern? whitespace in the first string
-// may be deleted or replaced with other whitespace to match the pattern.
-// this function is unicode-ignorant; fortunately, the careful design of
-// UTF-8 mitigates this ignorance. In particular, this function only collapses
-// sequences of \n, \r, ' ', and \t, but it should otherwise tolerate unicode
-// chars. Unsurprisingly, it doesn't do NKF-normalization(?).
+/// Does the given string match the pattern? whitespace in the first string
+/// may be deleted or replaced with other whitespace to match the pattern.
+/// this function is unicode-ignorant; fortunately, the careful design of
+/// UTF-8 mitigates this ignorance. In particular, this function only collapses
+/// sequences of \n, \r, ' ', and \t, but it should otherwise tolerate unicode
+/// chars. Unsurprisingly, it doesn't do NKF-normalization(?).
pub fn matches_codepattern(a : &str, b : &str) -> bool {
let mut idx_a = 0;
let mut idx_b = 0;
}
}
-// given a string and an index, return the first uint >= idx
-// that is a non-ws-char or is outside of the legal range of
-// the string.
+/// Given a string and an index, return the first uint >= idx
+/// that is a non-ws-char or is outside of the legal range of
+/// the string.
fn scan_for_non_ws_or_end(a : &str, idx: uint) -> uint {
let mut i = idx;
let len = a.len();
i
}
-// copied from lexer.
+/// Copied from lexer.
pub fn is_whitespace(c: char) -> bool {
return c == ' ' || c == '\t' || c == '\r' || c == '\n';
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+//! Context-passing AST walker. Each overridden visit method has full control
+//! over what happens with its node, it can do its own traversal of the node's
+//! children (potentially passing in different contexts to each), call
+//! `visit::visit_*` to apply the default traversal algorithm (again, it can
+//! override the context), or prevent deeper traversal by doing nothing.
+//!
+//! Note: it is an important invariant that the default visitor walks the body
+//! of a function in "execution order" (more concretely, reverse post-order
+//! with respect to the CFG implied by the AST), meaning that if AST node A may
+//! execute before AST node B, then A is visited first. The borrow checker in
+//! particular relies on this property.
+//!
+//! Note: walking an AST before macro expansion is probably a bad idea. For
+//! instance, a walker looking for item names in a module will miss all of
+//! those that are created by the expansion of a macro.
+
use abi::Abi;
use ast::*;
use ast;
use std::gc::Gc;
-// Context-passing AST walker. Each overridden visit method has full control
-// over what happens with its node, it can do its own traversal of the node's
-// children (potentially passing in different contexts to each), call
-// visit::visit_* to apply the default traversal algorithm (again, it can
-// override the context), or prevent deeper traversal by doing nothing.
-//
-// Note: it is an important invariant that the default visitor walks the body
-// of a function in "execution order" (more concretely, reverse post-order
-// with respect to the CFG implied by the AST), meaning that if AST node A may
-// execute before AST node B, then A is visited first. The borrow checker in
-// particular relies on this property.
-
pub enum FnKind<'a> {
- // fn foo() or extern "Abi" fn foo()
+ /// fn foo() or extern "Abi" fn foo()
FkItemFn(Ident, &'a Generics, FnStyle, Abi),
- // fn foo(&self)
+ /// fn foo(&self)
FkMethod(Ident, &'a Generics, &'a Method),
- // |x, y| ...
- // proc(x, y) ...
+ /// |x, y| ...
+ /// proc(x, y) ...
FkFnBlock,
}
fn visit_explicit_self(&mut self, es: &ExplicitSelf, e: E) {
walk_explicit_self(self, es, e)
}
- fn visit_mac(&mut self, macro: &Mac, e: E) {
- walk_mac(self, macro, e)
+ fn visit_mac(&mut self, _macro: &Mac, _e: E) {
+ fail!("visit_mac disabled by default");
+ // NB: see note about macros above.
+ // if you really want a visitor that
+ // works on macros, use this
+ // definition in your trait impl:
+ // visit::walk_mac(self, _macro, _e)
}
fn visit_path(&mut self, path: &Path, _id: ast::NodeId, e: E) {
walk_path(self, path, e)
explicit_self: &ExplicitSelf,
env: E) {
match explicit_self.node {
- SelfStatic | SelfValue | SelfUniq => {}
- SelfRegion(ref lifetime, _) => {
+ SelfStatic | SelfValue(_) | SelfUniq(_) => {},
+ SelfRegion(ref lifetime, _, _) => {
visitor.visit_opt_lifetime_ref(explicit_self.span, lifetime, env)
}
}
pub fn walk_method_helper<E: Clone, V: Visitor<E>>(visitor: &mut V,
method: &Method,
env: E) {
- visitor.visit_ident(method.span, method.ident, env.clone());
- visitor.visit_fn(&FkMethod(method.ident, &method.generics, method),
- &*method.decl,
- &*method.body,
- method.span,
- method.id,
- env.clone());
- for attr in method.attrs.iter() {
- visitor.visit_attribute(attr, env.clone());
+ match method.node {
+ MethDecl(ident, ref generics, _, _, decl, body, _) => {
+ visitor.visit_ident(method.span, ident, env.clone());
+ visitor.visit_fn(&FkMethod(ident, generics, method),
+ decl,
+ body,
+ method.span,
+ method.id,
+ env.clone());
+ for attr in method.attrs.iter() {
+ visitor.visit_attribute(attr, env.clone());
+ }
+
+ },
+ MethMac(ref mac) => visitor.visit_mac(mac, env.clone())
}
}
}
FkMethod(_, generics, method) => {
visitor.visit_generics(generics, env.clone());
-
- visitor.visit_explicit_self(&method.explicit_self, env.clone());
+ match method.node {
+ MethDecl(_, _, ref explicit_self, _, _, _, _) =>
+ visitor.visit_explicit_self(explicit_self, env.clone()),
+ MethMac(ref mac) =>
+ visitor.visit_mac(mac, env.clone())
+ }
}
FkFnBlock(..) => {}
}
//! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx
//! [ti]: https://en.wikipedia.org/wiki/Terminfo
-#![crate_id = "term#0.11.0"]
+#![crate_name = "term"]
#![experimental]
#![comment = "Simple ANSI color library"]
#![license = "MIT/ASL2"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
#![feature(macro_rules, phase)]
// These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
-pub static boolfnames: &'static[&'static str] = &'static["auto_left_margin", "auto_right_margin",
+pub static boolfnames: &'static[&'static str] = &["auto_left_margin", "auto_right_margin",
"no_esc_ctlc", "ceol_standout_glitch", "eat_newline_glitch", "erase_overstrike", "generic_type",
"hard_copy", "has_meta_key", "has_status_line", "insert_null_glitch", "memory_above",
"memory_below", "move_insert_mode", "move_standout_mode", "over_strike", "status_line_esc_ok",
"no_correctly_working_cr", "gnu_has_meta_key", "linefeed_is_newline", "has_hardware_tabs",
"return_does_clr_eol"];
-pub static boolnames: &'static[&'static str] = &'static["bw", "am", "xsb", "xhp", "xenl", "eo",
+pub static boolnames: &'static[&'static str] = &["bw", "am", "xsb", "xhp", "xenl", "eo",
"gn", "hc", "km", "hs", "in", "db", "da", "mir", "msgr", "os", "eslok", "xt", "hz", "ul", "xon",
"nxon", "mc5i", "chts", "nrrmc", "npc", "ndscr", "ccc", "bce", "hls", "xhpa", "crxm", "daisy",
"xvpa", "sam", "cpix", "lpix", "OTbs", "OTns", "OTnc", "OTMT", "OTNL", "OTpt", "OTxr"];
-pub static numfnames: &'static[&'static str] = &'static[ "columns", "init_tabs", "lines",
+pub static numfnames: &'static[&'static str] = &[ "columns", "init_tabs", "lines",
"lines_of_memory", "magic_cookie_glitch", "padding_baud_rate", "virtual_terminal",
"width_status_line", "num_labels", "label_height", "label_width", "max_attributes",
"maximum_windows", "max_colors", "max_pairs", "no_color_video", "buffer_capacity",
"bit_image_entwining", "bit_image_type", "magic_cookie_glitch_ul", "carriage_return_delay",
"new_line_delay", "backspace_delay", "horizontal_tab_delay", "number_of_function_keys"];
-pub static numnames: &'static[&'static str] = &'static[ "cols", "it", "lines", "lm", "xmc", "pb",
+pub static numnames: &'static[&'static str] = &[ "cols", "it", "lines", "lm", "xmc", "pb",
"vt", "wsl", "nlab", "lh", "lw", "ma", "wnum", "colors", "pairs", "ncv", "bufsz", "spinv",
"spinh", "maddr", "mjump", "mcs", "mls", "npins", "orc", "orl", "orhi", "orvi", "cps", "widcs",
"btns", "bitwin", "bitype", "UTug", "OTdC", "OTdN", "OTdB", "OTdT", "OTkn"];
-pub static stringfnames: &'static[&'static str] = &'static[ "back_tab", "bell", "carriage_return",
+pub static stringfnames: &'static[&'static str] = &[ "back_tab", "bell", "carriage_return",
"change_scroll_region", "clear_all_tabs", "clear_screen", "clr_eol", "clr_eos",
"column_address", "command_character", "cursor_address", "cursor_down", "cursor_home",
"cursor_invisible", "cursor_left", "cursor_mem_address", "cursor_normal", "cursor_right",
"acs_lrcorner", "acs_ltee", "acs_rtee", "acs_btee", "acs_ttee", "acs_hline", "acs_vline",
"acs_plus", "memory_lock", "memory_unlock", "box_chars_1"];
-pub static stringnames: &'static[&'static str] = &'static[ "cbt", "_", "cr", "csr", "tbc", "clear",
+pub static stringnames: &'static[&'static str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear",
"_", "_", "hpa", "cmdch", "cup", "cud1", "home", "civis", "cub1", "mrcup", "cnorm", "cuf1",
"ll", "cuu1", "cvvis", "dch1", "dl1", "dsl", "hd", "smacs", "blink", "bold", "smcup", "smdc",
"dim", "smir", "invis", "prot", "rev", "smso", "smul", "ech", "rmacs", "sgr0", "rmcup", "rmdc",
// running tests while providing a base that other test frameworks may
// build off of.
-#![crate_id = "test#0.11.0"]
+#![crate_name = "test"]
#![experimental]
#![comment = "Rust internal test library only used by rustc"]
#![license = "MIT/ASL2"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/")]
+ html_root_url = "http://doc.rust-lang.org/master/")]
#![feature(asm, macro_rules, phase)]
let matches =
match getopts::getopts(args_.as_slice(), optgroups().as_slice()) {
Ok(m) => m,
- Err(f) => return Some(Err(f.to_str()))
+ Err(f) => return Some(Err(f.to_string()))
};
if matches.opt_present("h") { usage(args[0].as_slice()); return None; }
let mut failures = Vec::new();
let mut fail_out = String::new();
for &(ref f, ref stdout) in self.failures.iter() {
- failures.push(f.name.to_str());
+ failures.push(f.name.to_string());
if stdout.len() > 0 {
fail_out.push_str(format!("---- {} stdout ----\n\t",
f.name.as_slice()).as_slice());
let filtered = filter_tests(&opts, tests);
assert_eq!(filtered.len(), 1);
- assert_eq!(filtered.get(0).desc.name.to_str(),
+ assert_eq!(filtered.get(0).desc.name.to_string(),
"1".to_string());
assert!(filtered.get(0).desc.ignore == false);
}
"test::sort_tests".to_string());
for (a, b) in expected.iter().zip(filtered.iter()) {
- assert!(*a == b.desc.name.to_str());
+ assert!(*a == b.desc.name.to_string());
}
}
let range = hi - lo;
- let lostr = lo.to_str();
- let histr = hi.to_str();
+ let lostr = lo.to_string();
+ let histr = hi.to_string();
let overhead_width = lostr.len() + histr.len() + 4;
let range_width = width_hint - overhead_width;
//! Simple time handling.
-#![crate_id = "time#0.11.0"]
+#![crate_name = "time"]
#![experimental]
#![crate_type = "rlib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
#![feature(phase)]
'U' => format!("{:02d}", (tm.tm_yday - tm.tm_wday + 7) / 7),
'u' => {
let i = tm.tm_wday as int;
- (if i == 0 { 7 } else { i }).to_str()
+ (if i == 0 { 7 } else { i }).to_string()
}
'V' => iso_week('V', tm),
'v' => {
format!("{:02d}",
(tm.tm_yday - (tm.tm_wday - 1 + 7) % 7 + 7) / 7)
}
- 'w' => (tm.tm_wday as int).to_str(),
- 'Y' => (tm.tm_year as int + 1900).to_str(),
+ 'w' => (tm.tm_wday as int).to_string(),
+ 'Y' => (tm.tm_year as int + 1900).to_string(),
'y' => format!("{:02d}", (tm.tm_year as int + 1900) % 100),
'Z' => "".to_string(), // FIXME(pcwalton): Implement this.
'z' => {
--- /dev/null
+// Copyright 2012-2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+ Functions for computing canonical and compatible decompositions
+ for Unicode characters.
+ */
+
+use core::option::{Option, Some, None};
+use core::slice::ImmutableVector;
+use tables::normalization::{canonical_table, compatibility_table};
+
+fn bsearch_table(c: char, r: &'static [(char, &'static [char])]) -> Option<&'static [char]> {
+ use core::cmp::{Equal, Less, Greater};
+ match r.bsearch(|&(val, _)| {
+ if c == val { Equal }
+ else if val < c { Less }
+ else { Greater }
+ }) {
+ Some(idx) => {
+ let (_, result) = r[idx];
+ Some(result)
+ }
+ None => None
+ }
+}
+
+/// Compute canonical Unicode decomposition for character
+pub fn decompose_canonical(c: char, i: |char|) { d(c, i, false); }
+
+/// Compute canonical or compatible Unicode decomposition for character
+pub fn decompose_compatible(c: char, i: |char|) { d(c, i, true); }
+
+fn d(c: char, i: |char|, k: bool) {
+ use core::iter::Iterator;
+
+ // 7-bit ASCII never decomposes
+ if c <= '\x7f' { i(c); return; }
+
+ // Perform decomposition for Hangul
+ if (c as u32) >= S_BASE && (c as u32) < (S_BASE + S_COUNT) {
+ decompose_hangul(c, i);
+ return;
+ }
+
+ // First check the canonical decompositions
+ match bsearch_table(c, canonical_table) {
+ Some(canon) => {
+ for x in canon.iter() {
+ d(*x, |b| i(b), k);
+ }
+ return;
+ }
+ None => ()
+ }
+
+ // Bottom out if we're not doing compat.
+ if !k { i(c); return; }
+
+ // Then check the compatibility decompositions
+ match bsearch_table(c, compatibility_table) {
+ Some(compat) => {
+ for x in compat.iter() {
+ d(*x, |b| i(b), k);
+ }
+ return;
+ }
+ None => ()
+ }
+
+ // Finally bottom out.
+ i(c);
+}
+
+// Constants from Unicode 6.3.0 Section 3.12 Conjoining Jamo Behavior
+static S_BASE: u32 = 0xAC00;
+static L_BASE: u32 = 0x1100;
+static V_BASE: u32 = 0x1161;
+static T_BASE: u32 = 0x11A7;
+static L_COUNT: u32 = 19;
+static V_COUNT: u32 = 21;
+static T_COUNT: u32 = 28;
+static N_COUNT: u32 = (V_COUNT * T_COUNT);
+static S_COUNT: u32 = (L_COUNT * N_COUNT);
+
+// Decompose a precomposed Hangul syllable
+fn decompose_hangul(s: char, f: |char|) {
+ use core::mem::transmute;
+
+ let si = s as u32 - S_BASE;
+
+ let li = si / N_COUNT;
+ unsafe {
+ f(transmute(L_BASE + li));
+
+ let vi = (si % N_COUNT) / T_COUNT;
+ f(transmute(V_BASE + vi));
+
+ let ti = si % T_COUNT;
+ if ti > 0 {
+ f(transmute(T_BASE + ti));
+ }
+ }
+}
--- /dev/null
+// Copyright 2012-2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! # The Unicode Library
+//!
+//! Unicode-intensive functions for `char` and `str` types.
+//!
+//! This crate provides a collection of Unicode-related functionality,
+//! including decompositions, conversions, etc., and provides traits
+//! implementing these functions for the `char` and `str` types.
+//!
+//! The functionality included here is only that which is necessary to
+//! provide for basic string-related manipulations. This crate does not
+//! (yet) aim to provide a full set of Unicode tables.
+
+#![crate_name = "unicode"]
+#![experimental]
+#![license = "MIT/ASL2"]
+#![crate_type = "rlib"]
+#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+ html_favicon_url = "http://www.rust-lang.org/favicon.ico",
+ html_root_url = "http://doc.rust-lang.org/",
+ html_playground_url = "http://play.rust-lang.org/")]
+#![no_std]
+#![allow(unused_attribute)] // NOTE: remove after stage0
+
+extern crate core;
+
+pub use tables::normalization::canonical_combining_class;
+pub use tables::regex;
+
+pub use u_char::UnicodeChar;
+pub use u_str::UnicodeStrSlice;
+pub use u_str::Words;
+
+mod decompose;
+mod tables;
+mod u_char;
+mod u_str;
+
+// re-export char so that std et al see it correctly
+/// Character manipulation (`char` type, Unicode Scalar Value)
+///
+/// This module provides the `Char` and `UnicodeChar` traits, as well as their
+/// implementation for the primitive `char` type, in order to allow basic character
+/// manipulation.
+///
+/// A `char` actually represents a
+/// *[Unicode Scalar Value](http://www.unicode.org/glossary/#unicode_scalar_value)*,
+/// as it can contain any Unicode code point except high-surrogate and
+/// low-surrogate code points.
+///
+/// As such, only values in the ranges \[0x0,0xD7FF\] and \[0xE000,0x10FFFF\]
+/// (inclusive) are allowed. A `char` can always be safely cast to a `u32`;
+/// however the converse is not always true due to the above range limits
+/// and, as such, should be performed via the `from_u32` function..
+pub mod char {
+ pub use core::char::{MAX, from_u32, is_digit_radix, to_digit};
+ pub use core::char::{from_digit, escape_unicode, escape_default};
+ pub use core::char::{len_utf8_bytes, Char};
+
+ pub use decompose::decompose_canonical;
+ pub use decompose::decompose_compatible;
+
+ pub use u_char::{is_alphabetic, is_XID_start, is_XID_continue};
+ pub use u_char::{is_lowercase, is_uppercase, is_whitespace};
+ pub use u_char::{is_alphanumeric, is_control, is_digit};
+ pub use u_char::{to_uppercase, to_lowercase, width, UnicodeChar};
+}
--- /dev/null
+// Copyright 2012-2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly
+
+#![allow(missing_doc, non_uppercase_statics, non_snake_case_functions)]
+
+fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
+ use core::cmp::{Equal, Less, Greater};
+ use core::slice::ImmutableVector;
+ use core::option::None;
+ r.bsearch(|&(lo,hi)| {
+ if lo <= c && c <= hi { Equal }
+ else if hi < c { Less }
+ else { Greater }
+ }) != None
+}
+
+pub mod general_category {
+ pub static C_table: &'static [(char, char)] = &[
+ ('\x00', '\x1f'), ('\x7f', '\x9f'), ('\xad', '\xad'), ('\u0600', '\u0605'), ('\u061c',
+ '\u061c'), ('\u06dd', '\u06dd'), ('\u070f', '\u070f'), ('\u180e', '\u180e'), ('\u200b',
+ '\u200f'), ('\u202a', '\u202e'), ('\u2060', '\u2064'), ('\u2066', '\u206f'), ('\ue000',
+ '\ue000'), ('\uf8ff', '\uf8ff'), ('\ufeff', '\ufeff'), ('\ufff9', '\ufffb'), ('\U000110bd',
+ '\U000110bd'), ('\U0001bca0', '\U0001bca3'), ('\U0001d173', '\U0001d17a'), ('\U000e0001',
+ '\U000e0001'), ('\U000e0020', '\U000e007f'), ('\U000f0000', '\U000f0000'), ('\U000ffffd',
+ '\U000ffffd'), ('\U00100000', '\U00100000'), ('\U0010fffd', '\U0010fffd')
+ ];
+
+ pub static Cc_table: &'static [(char, char)] = &[
+ ('\x00', '\x1f'), ('\x7f', '\x9f')
+ ];
+
+ pub fn Cc(c: char) -> bool {
+ super::bsearch_range_table(c, Cc_table)
+ }
+
+ pub static Cf_table: &'static [(char, char)] = &[
+ ('\xad', '\xad'), ('\u0600', '\u0605'), ('\u061c', '\u061c'), ('\u06dd', '\u06dd'),
+ ('\u070f', '\u070f'), ('\u180e', '\u180e'), ('\u200b', '\u200f'), ('\u202a', '\u202e'),
+ ('\u2060', '\u2064'), ('\u2066', '\u206f'), ('\ufeff', '\ufeff'), ('\ufff9', '\ufffb'),
+ ('\U000110bd', '\U000110bd'), ('\U0001bca0', '\U0001bca3'), ('\U0001d173', '\U0001d17a'),
+ ('\U000e0001', '\U000e0001'), ('\U000e0020', '\U000e007f')
+ ];
+
+ pub static Co_table: &'static [(char, char)] = &[
+ ('\ue000', '\ue000'), ('\uf8ff', '\uf8ff'), ('\U000f0000', '\U000f0000'), ('\U000ffffd',
+ '\U000ffffd'), ('\U00100000', '\U00100000'), ('\U0010fffd', '\U0010fffd')
+ ];
+
+ pub static L_table: &'static [(char, char)] = &[
+ ('\x41', '\x5a'), ('\x61', '\x7a'), ('\xaa', '\xaa'), ('\xb5', '\xb5'), ('\xba', '\xba'),
+ ('\xc0', '\xd6'), ('\xd8', '\xf6'), ('\xf8', '\u02c1'), ('\u02c6', '\u02d1'), ('\u02e0',
+ '\u02e4'), ('\u02ec', '\u02ec'), ('\u02ee', '\u02ee'), ('\u0370', '\u0374'), ('\u0376',
+ '\u0377'), ('\u037a', '\u037d'), ('\u037f', '\u037f'), ('\u0386', '\u0386'), ('\u0388',
+ '\u038a'), ('\u038c', '\u038c'), ('\u038e', '\u03a1'), ('\u03a3', '\u03f5'), ('\u03f7',
+ '\u0481'), ('\u048a', '\u052f'), ('\u0531', '\u0556'), ('\u0559', '\u0559'), ('\u0561',
+ '\u0587'), ('\u05d0', '\u05ea'), ('\u05f0', '\u05f2'), ('\u0620', '\u064a'), ('\u066e',
+ '\u066f'), ('\u0671', '\u06d3'), ('\u06d5', '\u06d5'), ('\u06e5', '\u06e6'), ('\u06ee',
+ '\u06ef'), ('\u06fa', '\u06fc'), ('\u06ff', '\u06ff'), ('\u0710', '\u0710'), ('\u0712',
+ '\u072f'), ('\u074d', '\u07a5'), ('\u07b1', '\u07b1'), ('\u07ca', '\u07ea'), ('\u07f4',
+ '\u07f5'), ('\u07fa', '\u07fa'), ('\u0800', '\u0815'), ('\u081a', '\u081a'), ('\u0824',
+ '\u0824'), ('\u0828', '\u0828'), ('\u0840', '\u0858'), ('\u08a0', '\u08b2'), ('\u0904',
+ '\u0939'), ('\u093d', '\u093d'), ('\u0950', '\u0950'), ('\u0958', '\u0961'), ('\u0971',
+ '\u0980'), ('\u0985', '\u098c'), ('\u098f', '\u0990'), ('\u0993', '\u09a8'), ('\u09aa',
+ '\u09b0'), ('\u09b2', '\u09b2'), ('\u09b6', '\u09b9'), ('\u09bd', '\u09bd'), ('\u09ce',
+ '\u09ce'), ('\u09dc', '\u09dd'), ('\u09df', '\u09e1'), ('\u09f0', '\u09f1'), ('\u0a05',
+ '\u0a0a'), ('\u0a0f', '\u0a10'), ('\u0a13', '\u0a28'), ('\u0a2a', '\u0a30'), ('\u0a32',
+ '\u0a33'), ('\u0a35', '\u0a36'), ('\u0a38', '\u0a39'), ('\u0a59', '\u0a5c'), ('\u0a5e',
+ '\u0a5e'), ('\u0a72', '\u0a74'), ('\u0a85', '\u0a8d'), ('\u0a8f', '\u0a91'), ('\u0a93',
+ '\u0aa8'), ('\u0aaa', '\u0ab0'), ('\u0ab2', '\u0ab3'), ('\u0ab5', '\u0ab9'), ('\u0abd',
+ '\u0abd'), ('\u0ad0', '\u0ad0'), ('\u0ae0', '\u0ae1'), ('\u0b05', '\u0b0c'), ('\u0b0f',
+ '\u0b10'), ('\u0b13', '\u0b28'), ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'), ('\u0b35',
+ '\u0b39'), ('\u0b3d', '\u0b3d'), ('\u0b5c', '\u0b5d'), ('\u0b5f', '\u0b61'), ('\u0b71',
+ '\u0b71'), ('\u0b83', '\u0b83'), ('\u0b85', '\u0b8a'), ('\u0b8e', '\u0b90'), ('\u0b92',
+ '\u0b95'), ('\u0b99', '\u0b9a'), ('\u0b9c', '\u0b9c'), ('\u0b9e', '\u0b9f'), ('\u0ba3',
+ '\u0ba4'), ('\u0ba8', '\u0baa'), ('\u0bae', '\u0bb9'), ('\u0bd0', '\u0bd0'), ('\u0c05',
+ '\u0c0c'), ('\u0c0e', '\u0c10'), ('\u0c12', '\u0c28'), ('\u0c2a', '\u0c39'), ('\u0c3d',
+ '\u0c3d'), ('\u0c58', '\u0c59'), ('\u0c60', '\u0c61'), ('\u0c85', '\u0c8c'), ('\u0c8e',
+ '\u0c90'), ('\u0c92', '\u0ca8'), ('\u0caa', '\u0cb3'), ('\u0cb5', '\u0cb9'), ('\u0cbd',
+ '\u0cbd'), ('\u0cde', '\u0cde'), ('\u0ce0', '\u0ce1'), ('\u0cf1', '\u0cf2'), ('\u0d05',
+ '\u0d0c'), ('\u0d0e', '\u0d10'), ('\u0d12', '\u0d3a'), ('\u0d3d', '\u0d3d'), ('\u0d4e',
+ '\u0d4e'), ('\u0d60', '\u0d61'), ('\u0d7a', '\u0d7f'), ('\u0d85', '\u0d96'), ('\u0d9a',
+ '\u0db1'), ('\u0db3', '\u0dbb'), ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'), ('\u0e01',
+ '\u0e30'), ('\u0e32', '\u0e33'), ('\u0e40', '\u0e46'), ('\u0e81', '\u0e82'), ('\u0e84',
+ '\u0e84'), ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'), ('\u0e8d', '\u0e8d'), ('\u0e94',
+ '\u0e97'), ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'), ('\u0ea5', '\u0ea5'), ('\u0ea7',
+ '\u0ea7'), ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'), ('\u0eb2', '\u0eb3'), ('\u0ebd',
+ '\u0ebd'), ('\u0ec0', '\u0ec4'), ('\u0ec6', '\u0ec6'), ('\u0edc', '\u0edf'), ('\u0f00',
+ '\u0f00'), ('\u0f40', '\u0f47'), ('\u0f49', '\u0f6c'), ('\u0f88', '\u0f8c'), ('\u1000',
+ '\u102a'), ('\u103f', '\u103f'), ('\u1050', '\u1055'), ('\u105a', '\u105d'), ('\u1061',
+ '\u1061'), ('\u1065', '\u1066'), ('\u106e', '\u1070'), ('\u1075', '\u1081'), ('\u108e',
+ '\u108e'), ('\u10a0', '\u10c5'), ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'), ('\u10d0',
+ '\u10fa'), ('\u10fc', '\u1248'), ('\u124a', '\u124d'), ('\u1250', '\u1256'), ('\u1258',
+ '\u1258'), ('\u125a', '\u125d'), ('\u1260', '\u1288'), ('\u128a', '\u128d'), ('\u1290',
+ '\u12b0'), ('\u12b2', '\u12b5'), ('\u12b8', '\u12be'), ('\u12c0', '\u12c0'), ('\u12c2',
+ '\u12c5'), ('\u12c8', '\u12d6'), ('\u12d8', '\u1310'), ('\u1312', '\u1315'), ('\u1318',
+ '\u135a'), ('\u1380', '\u138f'), ('\u13a0', '\u13f4'), ('\u1401', '\u166c'), ('\u166f',
+ '\u167f'), ('\u1681', '\u169a'), ('\u16a0', '\u16ea'), ('\u16f1', '\u16f8'), ('\u1700',
+ '\u170c'), ('\u170e', '\u1711'), ('\u1720', '\u1731'), ('\u1740', '\u1751'), ('\u1760',
+ '\u176c'), ('\u176e', '\u1770'), ('\u1780', '\u17b3'), ('\u17d7', '\u17d7'), ('\u17dc',
+ '\u17dc'), ('\u1820', '\u1877'), ('\u1880', '\u18a8'), ('\u18aa', '\u18aa'), ('\u18b0',
+ '\u18f5'), ('\u1900', '\u191e'), ('\u1950', '\u196d'), ('\u1970', '\u1974'), ('\u1980',
+ '\u19ab'), ('\u19c1', '\u19c7'), ('\u1a00', '\u1a16'), ('\u1a20', '\u1a54'), ('\u1aa7',
+ '\u1aa7'), ('\u1b05', '\u1b33'), ('\u1b45', '\u1b4b'), ('\u1b83', '\u1ba0'), ('\u1bae',
+ '\u1baf'), ('\u1bba', '\u1be5'), ('\u1c00', '\u1c23'), ('\u1c4d', '\u1c4f'), ('\u1c5a',
+ '\u1c7d'), ('\u1ce9', '\u1cec'), ('\u1cee', '\u1cf1'), ('\u1cf5', '\u1cf6'), ('\u1d00',
+ '\u1dbf'), ('\u1e00', '\u1f15'), ('\u1f18', '\u1f1d'), ('\u1f20', '\u1f45'), ('\u1f48',
+ '\u1f4d'), ('\u1f50', '\u1f57'), ('\u1f59', '\u1f59'), ('\u1f5b', '\u1f5b'), ('\u1f5d',
+ '\u1f5d'), ('\u1f5f', '\u1f7d'), ('\u1f80', '\u1fb4'), ('\u1fb6', '\u1fbc'), ('\u1fbe',
+ '\u1fbe'), ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fcc'), ('\u1fd0', '\u1fd3'), ('\u1fd6',
+ '\u1fdb'), ('\u1fe0', '\u1fec'), ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ffc'), ('\u2071',
+ '\u2071'), ('\u207f', '\u207f'), ('\u2090', '\u209c'), ('\u2102', '\u2102'), ('\u2107',
+ '\u2107'), ('\u210a', '\u2113'), ('\u2115', '\u2115'), ('\u2119', '\u211d'), ('\u2124',
+ '\u2124'), ('\u2126', '\u2126'), ('\u2128', '\u2128'), ('\u212a', '\u212d'), ('\u212f',
+ '\u2139'), ('\u213c', '\u213f'), ('\u2145', '\u2149'), ('\u214e', '\u214e'), ('\u2183',
+ '\u2184'), ('\u2c00', '\u2c2e'), ('\u2c30', '\u2c5e'), ('\u2c60', '\u2ce4'), ('\u2ceb',
+ '\u2cee'), ('\u2cf2', '\u2cf3'), ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'), ('\u2d2d',
+ '\u2d2d'), ('\u2d30', '\u2d67'), ('\u2d6f', '\u2d6f'), ('\u2d80', '\u2d96'), ('\u2da0',
+ '\u2da6'), ('\u2da8', '\u2dae'), ('\u2db0', '\u2db6'), ('\u2db8', '\u2dbe'), ('\u2dc0',
+ '\u2dc6'), ('\u2dc8', '\u2dce'), ('\u2dd0', '\u2dd6'), ('\u2dd8', '\u2dde'), ('\u2e2f',
+ '\u2e2f'), ('\u3005', '\u3006'), ('\u3031', '\u3035'), ('\u303b', '\u303c'), ('\u3041',
+ '\u3096'), ('\u309d', '\u309f'), ('\u30a1', '\u30fa'), ('\u30fc', '\u30ff'), ('\u3105',
+ '\u312d'), ('\u3131', '\u318e'), ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'), ('\u3400',
+ '\u3400'), ('\u4db5', '\u4db5'), ('\u4e00', '\u4e00'), ('\u9fcc', '\u9fcc'), ('\ua000',
+ '\ua48c'), ('\ua4d0', '\ua4fd'), ('\ua500', '\ua60c'), ('\ua610', '\ua61f'), ('\ua62a',
+ '\ua62b'), ('\ua640', '\ua66e'), ('\ua67f', '\ua69d'), ('\ua6a0', '\ua6e5'), ('\ua717',
+ '\ua71f'), ('\ua722', '\ua788'), ('\ua78b', '\ua78e'), ('\ua790', '\ua7ad'), ('\ua7b0',
+ '\ua7b1'), ('\ua7f7', '\ua801'), ('\ua803', '\ua805'), ('\ua807', '\ua80a'), ('\ua80c',
+ '\ua822'), ('\ua840', '\ua873'), ('\ua882', '\ua8b3'), ('\ua8f2', '\ua8f7'), ('\ua8fb',
+ '\ua8fb'), ('\ua90a', '\ua925'), ('\ua930', '\ua946'), ('\ua960', '\ua97c'), ('\ua984',
+ '\ua9b2'), ('\ua9cf', '\ua9cf'), ('\ua9e0', '\ua9e4'), ('\ua9e6', '\ua9ef'), ('\ua9fa',
+ '\ua9fe'), ('\uaa00', '\uaa28'), ('\uaa40', '\uaa42'), ('\uaa44', '\uaa4b'), ('\uaa60',
+ '\uaa76'), ('\uaa7a', '\uaa7a'), ('\uaa7e', '\uaaaf'), ('\uaab1', '\uaab1'), ('\uaab5',
+ '\uaab6'), ('\uaab9', '\uaabd'), ('\uaac0', '\uaac0'), ('\uaac2', '\uaac2'), ('\uaadb',
+ '\uaadd'), ('\uaae0', '\uaaea'), ('\uaaf2', '\uaaf4'), ('\uab01', '\uab06'), ('\uab09',
+ '\uab0e'), ('\uab11', '\uab16'), ('\uab20', '\uab26'), ('\uab28', '\uab2e'), ('\uab30',
+ '\uab5a'), ('\uab5c', '\uab5f'), ('\uab64', '\uab65'), ('\uabc0', '\uabe2'), ('\uac00',
+ '\uac00'), ('\ud7a3', '\ud7a3'), ('\ud7b0', '\ud7c6'), ('\ud7cb', '\ud7fb'), ('\uf900',
+ '\ufa6d'), ('\ufa70', '\ufad9'), ('\ufb00', '\ufb06'), ('\ufb13', '\ufb17'), ('\ufb1d',
+ '\ufb1d'), ('\ufb1f', '\ufb28'), ('\ufb2a', '\ufb36'), ('\ufb38', '\ufb3c'), ('\ufb3e',
+ '\ufb3e'), ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'), ('\ufb46', '\ufbb1'), ('\ufbd3',
+ '\ufd3d'), ('\ufd50', '\ufd8f'), ('\ufd92', '\ufdc7'), ('\ufdf0', '\ufdfb'), ('\ufe70',
+ '\ufe74'), ('\ufe76', '\ufefc'), ('\uff21', '\uff3a'), ('\uff41', '\uff5a'), ('\uff66',
+ '\uffbe'), ('\uffc2', '\uffc7'), ('\uffca', '\uffcf'), ('\uffd2', '\uffd7'), ('\uffda',
+ '\uffdc'), ('\U00010000', '\U0001000b'), ('\U0001000d', '\U00010026'), ('\U00010028',
+ '\U0001003a'), ('\U0001003c', '\U0001003d'), ('\U0001003f', '\U0001004d'), ('\U00010050',
+ '\U0001005d'), ('\U00010080', '\U000100fa'), ('\U00010280', '\U0001029c'), ('\U000102a0',
+ '\U000102d0'), ('\U00010300', '\U0001031f'), ('\U00010330', '\U00010340'), ('\U00010342',
+ '\U00010349'), ('\U00010350', '\U00010375'), ('\U00010380', '\U0001039d'), ('\U000103a0',
+ '\U000103c3'), ('\U000103c8', '\U000103cf'), ('\U00010400', '\U0001049d'), ('\U00010500',
+ '\U00010527'), ('\U00010530', '\U00010563'), ('\U00010600', '\U00010736'), ('\U00010740',
+ '\U00010755'), ('\U00010760', '\U00010767'), ('\U00010800', '\U00010805'), ('\U00010808',
+ '\U00010808'), ('\U0001080a', '\U00010835'), ('\U00010837', '\U00010838'), ('\U0001083c',
+ '\U0001083c'), ('\U0001083f', '\U00010855'), ('\U00010860', '\U00010876'), ('\U00010880',
+ '\U0001089e'), ('\U00010900', '\U00010915'), ('\U00010920', '\U00010939'), ('\U00010980',
+ '\U000109b7'), ('\U000109be', '\U000109bf'), ('\U00010a00', '\U00010a00'), ('\U00010a10',
+ '\U00010a13'), ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'), ('\U00010a60',
+ '\U00010a7c'), ('\U00010a80', '\U00010a9c'), ('\U00010ac0', '\U00010ac7'), ('\U00010ac9',
+ '\U00010ae4'), ('\U00010b00', '\U00010b35'), ('\U00010b40', '\U00010b55'), ('\U00010b60',
+ '\U00010b72'), ('\U00010b80', '\U00010b91'), ('\U00010c00', '\U00010c48'), ('\U00011003',
+ '\U00011037'), ('\U00011083', '\U000110af'), ('\U000110d0', '\U000110e8'), ('\U00011103',
+ '\U00011126'), ('\U00011150', '\U00011172'), ('\U00011176', '\U00011176'), ('\U00011183',
+ '\U000111b2'), ('\U000111c1', '\U000111c4'), ('\U000111da', '\U000111da'), ('\U00011200',
+ '\U00011211'), ('\U00011213', '\U0001122b'), ('\U000112b0', '\U000112de'), ('\U00011305',
+ '\U0001130c'), ('\U0001130f', '\U00011310'), ('\U00011313', '\U00011328'), ('\U0001132a',
+ '\U00011330'), ('\U00011332', '\U00011333'), ('\U00011335', '\U00011339'), ('\U0001133d',
+ '\U0001133d'), ('\U0001135d', '\U00011361'), ('\U00011480', '\U000114af'), ('\U000114c4',
+ '\U000114c5'), ('\U000114c7', '\U000114c7'), ('\U00011580', '\U000115ae'), ('\U00011600',
+ '\U0001162f'), ('\U00011644', '\U00011644'), ('\U00011680', '\U000116aa'), ('\U000118a0',
+ '\U000118df'), ('\U000118ff', '\U000118ff'), ('\U00011ac0', '\U00011af8'), ('\U00012000',
+ '\U00012398'), ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'), ('\U00016a40',
+ '\U00016a5e'), ('\U00016ad0', '\U00016aed'), ('\U00016b00', '\U00016b2f'), ('\U00016b40',
+ '\U00016b43'), ('\U00016b63', '\U00016b77'), ('\U00016b7d', '\U00016b8f'), ('\U00016f00',
+ '\U00016f44'), ('\U00016f50', '\U00016f50'), ('\U00016f93', '\U00016f9f'), ('\U0001b000',
+ '\U0001b001'), ('\U0001bc00', '\U0001bc6a'), ('\U0001bc70', '\U0001bc7c'), ('\U0001bc80',
+ '\U0001bc88'), ('\U0001bc90', '\U0001bc99'), ('\U0001d400', '\U0001d454'), ('\U0001d456',
+ '\U0001d49c'), ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5',
+ '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b9'), ('\U0001d4bb',
+ '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d505'), ('\U0001d507',
+ '\U0001d50a'), ('\U0001d50d', '\U0001d514'), ('\U0001d516', '\U0001d51c'), ('\U0001d51e',
+ '\U0001d539'), ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'), ('\U0001d546',
+ '\U0001d546'), ('\U0001d54a', '\U0001d550'), ('\U0001d552', '\U0001d6a5'), ('\U0001d6a8',
+ '\U0001d6c0'), ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6fa'), ('\U0001d6fc',
+ '\U0001d714'), ('\U0001d716', '\U0001d734'), ('\U0001d736', '\U0001d74e'), ('\U0001d750',
+ '\U0001d76e'), ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d7a8'), ('\U0001d7aa',
+ '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb'), ('\U0001e800', '\U0001e8c4'), ('\U0001ee00',
+ '\U0001ee03'), ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'), ('\U0001ee24',
+ '\U0001ee24'), ('\U0001ee27', '\U0001ee27'), ('\U0001ee29', '\U0001ee32'), ('\U0001ee34',
+ '\U0001ee37'), ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'), ('\U0001ee42',
+ '\U0001ee42'), ('\U0001ee47', '\U0001ee47'), ('\U0001ee49', '\U0001ee49'), ('\U0001ee4b',
+ '\U0001ee4b'), ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'), ('\U0001ee54',
+ '\U0001ee54'), ('\U0001ee57', '\U0001ee57'), ('\U0001ee59', '\U0001ee59'), ('\U0001ee5b',
+ '\U0001ee5b'), ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'), ('\U0001ee61',
+ '\U0001ee62'), ('\U0001ee64', '\U0001ee64'), ('\U0001ee67', '\U0001ee6a'), ('\U0001ee6c',
+ '\U0001ee72'), ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'), ('\U0001ee7e',
+ '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'), ('\U0001ee8b', '\U0001ee9b'), ('\U0001eea1',
+ '\U0001eea3'), ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'), ('\U00020000',
+ '\U00020000'), ('\U0002a6d6', '\U0002a6d6'), ('\U0002a700', '\U0002a700'), ('\U0002b734',
+ '\U0002b734'), ('\U0002b740', '\U0002b740'), ('\U0002b81d', '\U0002b81d'), ('\U0002f800',
+ '\U0002fa1d')
+ ];
+
+ pub static LC_table: &'static [(char, char)] = &[
+ ('\x41', '\x5a'), ('\x61', '\x7a'), ('\xb5', '\xb5'), ('\xc0', '\xd6'), ('\xd8', '\xf6'),
+ ('\xf8', '\u01ba'), ('\u01bc', '\u01bf'), ('\u01c4', '\u0293'), ('\u0295', '\u02af'),
+ ('\u0370', '\u0373'), ('\u0376', '\u0377'), ('\u037b', '\u037d'), ('\u037f', '\u037f'),
+ ('\u0386', '\u0386'), ('\u0388', '\u038a'), ('\u038c', '\u038c'), ('\u038e', '\u03a1'),
+ ('\u03a3', '\u03f5'), ('\u03f7', '\u0481'), ('\u048a', '\u052f'), ('\u0531', '\u0556'),
+ ('\u0561', '\u0587'), ('\u10a0', '\u10c5'), ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'),
+ ('\u1d00', '\u1d2b'), ('\u1d6b', '\u1d77'), ('\u1d79', '\u1d9a'), ('\u1e00', '\u1f15'),
+ ('\u1f18', '\u1f1d'), ('\u1f20', '\u1f45'), ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'),
+ ('\u1f59', '\u1f59'), ('\u1f5b', '\u1f5b'), ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'),
+ ('\u1f80', '\u1fb4'), ('\u1fb6', '\u1fbc'), ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'),
+ ('\u1fc6', '\u1fcc'), ('\u1fd0', '\u1fd3'), ('\u1fd6', '\u1fdb'), ('\u1fe0', '\u1fec'),
+ ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ffc'), ('\u2102', '\u2102'), ('\u2107', '\u2107'),
+ ('\u210a', '\u2113'), ('\u2115', '\u2115'), ('\u2119', '\u211d'), ('\u2124', '\u2124'),
+ ('\u2126', '\u2126'), ('\u2128', '\u2128'), ('\u212a', '\u212d'), ('\u212f', '\u2134'),
+ ('\u2139', '\u2139'), ('\u213c', '\u213f'), ('\u2145', '\u2149'), ('\u214e', '\u214e'),
+ ('\u2183', '\u2184'), ('\u2c00', '\u2c2e'), ('\u2c30', '\u2c5e'), ('\u2c60', '\u2c7b'),
+ ('\u2c7e', '\u2ce4'), ('\u2ceb', '\u2cee'), ('\u2cf2', '\u2cf3'), ('\u2d00', '\u2d25'),
+ ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'), ('\ua640', '\ua66d'), ('\ua680', '\ua69b'),
+ ('\ua722', '\ua76f'), ('\ua771', '\ua787'), ('\ua78b', '\ua78e'), ('\ua790', '\ua7ad'),
+ ('\ua7b0', '\ua7b1'), ('\ua7fa', '\ua7fa'), ('\uab30', '\uab5a'), ('\uab64', '\uab65'),
+ ('\ufb00', '\ufb06'), ('\ufb13', '\ufb17'), ('\uff21', '\uff3a'), ('\uff41', '\uff5a'),
+ ('\U00010400', '\U0001044f'), ('\U000118a0', '\U000118df'), ('\U0001d400', '\U0001d454'),
+ ('\U0001d456', '\U0001d49c'), ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'),
+ ('\U0001d4a5', '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b9'),
+ ('\U0001d4bb', '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d505'),
+ ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'), ('\U0001d516', '\U0001d51c'),
+ ('\U0001d51e', '\U0001d539'), ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'),
+ ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'), ('\U0001d552', '\U0001d6a5'),
+ ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6fa'),
+ ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d734'), ('\U0001d736', '\U0001d74e'),
+ ('\U0001d750', '\U0001d76e'), ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d7a8'),
+ ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb')
+ ];
+
+ pub static Ll_table: &'static [(char, char)] = &[
+ ('\x61', '\x7a'), ('\xb5', '\xb5'), ('\xdf', '\xf6'), ('\xf8', '\xff'), ('\u0101',
+ '\u0101'), ('\u0103', '\u0103'), ('\u0105', '\u0105'), ('\u0107', '\u0107'), ('\u0109',
+ '\u0109'), ('\u010b', '\u010b'), ('\u010d', '\u010d'), ('\u010f', '\u010f'), ('\u0111',
+ '\u0111'), ('\u0113', '\u0113'), ('\u0115', '\u0115'), ('\u0117', '\u0117'), ('\u0119',
+ '\u0119'), ('\u011b', '\u011b'), ('\u011d', '\u011d'), ('\u011f', '\u011f'), ('\u0121',
+ '\u0121'), ('\u0123', '\u0123'), ('\u0125', '\u0125'), ('\u0127', '\u0127'), ('\u0129',
+ '\u0129'), ('\u012b', '\u012b'), ('\u012d', '\u012d'), ('\u012f', '\u012f'), ('\u0131',
+ '\u0131'), ('\u0133', '\u0133'), ('\u0135', '\u0135'), ('\u0137', '\u0138'), ('\u013a',
+ '\u013a'), ('\u013c', '\u013c'), ('\u013e', '\u013e'), ('\u0140', '\u0140'), ('\u0142',
+ '\u0142'), ('\u0144', '\u0144'), ('\u0146', '\u0146'), ('\u0148', '\u0149'), ('\u014b',
+ '\u014b'), ('\u014d', '\u014d'), ('\u014f', '\u014f'), ('\u0151', '\u0151'), ('\u0153',
+ '\u0153'), ('\u0155', '\u0155'), ('\u0157', '\u0157'), ('\u0159', '\u0159'), ('\u015b',
+ '\u015b'), ('\u015d', '\u015d'), ('\u015f', '\u015f'), ('\u0161', '\u0161'), ('\u0163',
+ '\u0163'), ('\u0165', '\u0165'), ('\u0167', '\u0167'), ('\u0169', '\u0169'), ('\u016b',
+ '\u016b'), ('\u016d', '\u016d'), ('\u016f', '\u016f'), ('\u0171', '\u0171'), ('\u0173',
+ '\u0173'), ('\u0175', '\u0175'), ('\u0177', '\u0177'), ('\u017a', '\u017a'), ('\u017c',
+ '\u017c'), ('\u017e', '\u0180'), ('\u0183', '\u0183'), ('\u0185', '\u0185'), ('\u0188',
+ '\u0188'), ('\u018c', '\u018d'), ('\u0192', '\u0192'), ('\u0195', '\u0195'), ('\u0199',
+ '\u019b'), ('\u019e', '\u019e'), ('\u01a1', '\u01a1'), ('\u01a3', '\u01a3'), ('\u01a5',
+ '\u01a5'), ('\u01a8', '\u01a8'), ('\u01aa', '\u01ab'), ('\u01ad', '\u01ad'), ('\u01b0',
+ '\u01b0'), ('\u01b4', '\u01b4'), ('\u01b6', '\u01b6'), ('\u01b9', '\u01ba'), ('\u01bd',
+ '\u01bf'), ('\u01c6', '\u01c6'), ('\u01c9', '\u01c9'), ('\u01cc', '\u01cc'), ('\u01ce',
+ '\u01ce'), ('\u01d0', '\u01d0'), ('\u01d2', '\u01d2'), ('\u01d4', '\u01d4'), ('\u01d6',
+ '\u01d6'), ('\u01d8', '\u01d8'), ('\u01da', '\u01da'), ('\u01dc', '\u01dd'), ('\u01df',
+ '\u01df'), ('\u01e1', '\u01e1'), ('\u01e3', '\u01e3'), ('\u01e5', '\u01e5'), ('\u01e7',
+ '\u01e7'), ('\u01e9', '\u01e9'), ('\u01eb', '\u01eb'), ('\u01ed', '\u01ed'), ('\u01ef',
+ '\u01f0'), ('\u01f3', '\u01f3'), ('\u01f5', '\u01f5'), ('\u01f9', '\u01f9'), ('\u01fb',
+ '\u01fb'), ('\u01fd', '\u01fd'), ('\u01ff', '\u01ff'), ('\u0201', '\u0201'), ('\u0203',
+ '\u0203'), ('\u0205', '\u0205'), ('\u0207', '\u0207'), ('\u0209', '\u0209'), ('\u020b',
+ '\u020b'), ('\u020d', '\u020d'), ('\u020f', '\u020f'), ('\u0211', '\u0211'), ('\u0213',
+ '\u0213'), ('\u0215', '\u0215'), ('\u0217', '\u0217'), ('\u0219', '\u0219'), ('\u021b',
+ '\u021b'), ('\u021d', '\u021d'), ('\u021f', '\u021f'), ('\u0221', '\u0221'), ('\u0223',
+ '\u0223'), ('\u0225', '\u0225'), ('\u0227', '\u0227'), ('\u0229', '\u0229'), ('\u022b',
+ '\u022b'), ('\u022d', '\u022d'), ('\u022f', '\u022f'), ('\u0231', '\u0231'), ('\u0233',
+ '\u0239'), ('\u023c', '\u023c'), ('\u023f', '\u0240'), ('\u0242', '\u0242'), ('\u0247',
+ '\u0247'), ('\u0249', '\u0249'), ('\u024b', '\u024b'), ('\u024d', '\u024d'), ('\u024f',
+ '\u0293'), ('\u0295', '\u02af'), ('\u0371', '\u0371'), ('\u0373', '\u0373'), ('\u0377',
+ '\u0377'), ('\u037b', '\u037d'), ('\u0390', '\u0390'), ('\u03ac', '\u03ce'), ('\u03d0',
+ '\u03d1'), ('\u03d5', '\u03d7'), ('\u03d9', '\u03d9'), ('\u03db', '\u03db'), ('\u03dd',
+ '\u03dd'), ('\u03df', '\u03df'), ('\u03e1', '\u03e1'), ('\u03e3', '\u03e3'), ('\u03e5',
+ '\u03e5'), ('\u03e7', '\u03e7'), ('\u03e9', '\u03e9'), ('\u03eb', '\u03eb'), ('\u03ed',
+ '\u03ed'), ('\u03ef', '\u03f3'), ('\u03f5', '\u03f5'), ('\u03f8', '\u03f8'), ('\u03fb',
+ '\u03fc'), ('\u0430', '\u045f'), ('\u0461', '\u0461'), ('\u0463', '\u0463'), ('\u0465',
+ '\u0465'), ('\u0467', '\u0467'), ('\u0469', '\u0469'), ('\u046b', '\u046b'), ('\u046d',
+ '\u046d'), ('\u046f', '\u046f'), ('\u0471', '\u0471'), ('\u0473', '\u0473'), ('\u0475',
+ '\u0475'), ('\u0477', '\u0477'), ('\u0479', '\u0479'), ('\u047b', '\u047b'), ('\u047d',
+ '\u047d'), ('\u047f', '\u047f'), ('\u0481', '\u0481'), ('\u048b', '\u048b'), ('\u048d',
+ '\u048d'), ('\u048f', '\u048f'), ('\u0491', '\u0491'), ('\u0493', '\u0493'), ('\u0495',
+ '\u0495'), ('\u0497', '\u0497'), ('\u0499', '\u0499'), ('\u049b', '\u049b'), ('\u049d',
+ '\u049d'), ('\u049f', '\u049f'), ('\u04a1', '\u04a1'), ('\u04a3', '\u04a3'), ('\u04a5',
+ '\u04a5'), ('\u04a7', '\u04a7'), ('\u04a9', '\u04a9'), ('\u04ab', '\u04ab'), ('\u04ad',
+ '\u04ad'), ('\u04af', '\u04af'), ('\u04b1', '\u04b1'), ('\u04b3', '\u04b3'), ('\u04b5',
+ '\u04b5'), ('\u04b7', '\u04b7'), ('\u04b9', '\u04b9'), ('\u04bb', '\u04bb'), ('\u04bd',
+ '\u04bd'), ('\u04bf', '\u04bf'), ('\u04c2', '\u04c2'), ('\u04c4', '\u04c4'), ('\u04c6',
+ '\u04c6'), ('\u04c8', '\u04c8'), ('\u04ca', '\u04ca'), ('\u04cc', '\u04cc'), ('\u04ce',
+ '\u04cf'), ('\u04d1', '\u04d1'), ('\u04d3', '\u04d3'), ('\u04d5', '\u04d5'), ('\u04d7',
+ '\u04d7'), ('\u04d9', '\u04d9'), ('\u04db', '\u04db'), ('\u04dd', '\u04dd'), ('\u04df',
+ '\u04df'), ('\u04e1', '\u04e1'), ('\u04e3', '\u04e3'), ('\u04e5', '\u04e5'), ('\u04e7',
+ '\u04e7'), ('\u04e9', '\u04e9'), ('\u04eb', '\u04eb'), ('\u04ed', '\u04ed'), ('\u04ef',
+ '\u04ef'), ('\u04f1', '\u04f1'), ('\u04f3', '\u04f3'), ('\u04f5', '\u04f5'), ('\u04f7',
+ '\u04f7'), ('\u04f9', '\u04f9'), ('\u04fb', '\u04fb'), ('\u04fd', '\u04fd'), ('\u04ff',
+ '\u04ff'), ('\u0501', '\u0501'), ('\u0503', '\u0503'), ('\u0505', '\u0505'), ('\u0507',
+ '\u0507'), ('\u0509', '\u0509'), ('\u050b', '\u050b'), ('\u050d', '\u050d'), ('\u050f',
+ '\u050f'), ('\u0511', '\u0511'), ('\u0513', '\u0513'), ('\u0515', '\u0515'), ('\u0517',
+ '\u0517'), ('\u0519', '\u0519'), ('\u051b', '\u051b'), ('\u051d', '\u051d'), ('\u051f',
+ '\u051f'), ('\u0521', '\u0521'), ('\u0523', '\u0523'), ('\u0525', '\u0525'), ('\u0527',
+ '\u0527'), ('\u0529', '\u0529'), ('\u052b', '\u052b'), ('\u052d', '\u052d'), ('\u052f',
+ '\u052f'), ('\u0561', '\u0587'), ('\u1d00', '\u1d2b'), ('\u1d6b', '\u1d77'), ('\u1d79',
+ '\u1d9a'), ('\u1e01', '\u1e01'), ('\u1e03', '\u1e03'), ('\u1e05', '\u1e05'), ('\u1e07',
+ '\u1e07'), ('\u1e09', '\u1e09'), ('\u1e0b', '\u1e0b'), ('\u1e0d', '\u1e0d'), ('\u1e0f',
+ '\u1e0f'), ('\u1e11', '\u1e11'), ('\u1e13', '\u1e13'), ('\u1e15', '\u1e15'), ('\u1e17',
+ '\u1e17'), ('\u1e19', '\u1e19'), ('\u1e1b', '\u1e1b'), ('\u1e1d', '\u1e1d'), ('\u1e1f',
+ '\u1e1f'), ('\u1e21', '\u1e21'), ('\u1e23', '\u1e23'), ('\u1e25', '\u1e25'), ('\u1e27',
+ '\u1e27'), ('\u1e29', '\u1e29'), ('\u1e2b', '\u1e2b'), ('\u1e2d', '\u1e2d'), ('\u1e2f',
+ '\u1e2f'), ('\u1e31', '\u1e31'), ('\u1e33', '\u1e33'), ('\u1e35', '\u1e35'), ('\u1e37',
+ '\u1e37'), ('\u1e39', '\u1e39'), ('\u1e3b', '\u1e3b'), ('\u1e3d', '\u1e3d'), ('\u1e3f',
+ '\u1e3f'), ('\u1e41', '\u1e41'), ('\u1e43', '\u1e43'), ('\u1e45', '\u1e45'), ('\u1e47',
+ '\u1e47'), ('\u1e49', '\u1e49'), ('\u1e4b', '\u1e4b'), ('\u1e4d', '\u1e4d'), ('\u1e4f',
+ '\u1e4f'), ('\u1e51', '\u1e51'), ('\u1e53', '\u1e53'), ('\u1e55', '\u1e55'), ('\u1e57',
+ '\u1e57'), ('\u1e59', '\u1e59'), ('\u1e5b', '\u1e5b'), ('\u1e5d', '\u1e5d'), ('\u1e5f',
+ '\u1e5f'), ('\u1e61', '\u1e61'), ('\u1e63', '\u1e63'), ('\u1e65', '\u1e65'), ('\u1e67',
+ '\u1e67'), ('\u1e69', '\u1e69'), ('\u1e6b', '\u1e6b'), ('\u1e6d', '\u1e6d'), ('\u1e6f',
+ '\u1e6f'), ('\u1e71', '\u1e71'), ('\u1e73', '\u1e73'), ('\u1e75', '\u1e75'), ('\u1e77',
+ '\u1e77'), ('\u1e79', '\u1e79'), ('\u1e7b', '\u1e7b'), ('\u1e7d', '\u1e7d'), ('\u1e7f',
+ '\u1e7f'), ('\u1e81', '\u1e81'), ('\u1e83', '\u1e83'), ('\u1e85', '\u1e85'), ('\u1e87',
+ '\u1e87'), ('\u1e89', '\u1e89'), ('\u1e8b', '\u1e8b'), ('\u1e8d', '\u1e8d'), ('\u1e8f',
+ '\u1e8f'), ('\u1e91', '\u1e91'), ('\u1e93', '\u1e93'), ('\u1e95', '\u1e9d'), ('\u1e9f',
+ '\u1e9f'), ('\u1ea1', '\u1ea1'), ('\u1ea3', '\u1ea3'), ('\u1ea5', '\u1ea5'), ('\u1ea7',
+ '\u1ea7'), ('\u1ea9', '\u1ea9'), ('\u1eab', '\u1eab'), ('\u1ead', '\u1ead'), ('\u1eaf',
+ '\u1eaf'), ('\u1eb1', '\u1eb1'), ('\u1eb3', '\u1eb3'), ('\u1eb5', '\u1eb5'), ('\u1eb7',
+ '\u1eb7'), ('\u1eb9', '\u1eb9'), ('\u1ebb', '\u1ebb'), ('\u1ebd', '\u1ebd'), ('\u1ebf',
+ '\u1ebf'), ('\u1ec1', '\u1ec1'), ('\u1ec3', '\u1ec3'), ('\u1ec5', '\u1ec5'), ('\u1ec7',
+ '\u1ec7'), ('\u1ec9', '\u1ec9'), ('\u1ecb', '\u1ecb'), ('\u1ecd', '\u1ecd'), ('\u1ecf',
+ '\u1ecf'), ('\u1ed1', '\u1ed1'), ('\u1ed3', '\u1ed3'), ('\u1ed5', '\u1ed5'), ('\u1ed7',
+ '\u1ed7'), ('\u1ed9', '\u1ed9'), ('\u1edb', '\u1edb'), ('\u1edd', '\u1edd'), ('\u1edf',
+ '\u1edf'), ('\u1ee1', '\u1ee1'), ('\u1ee3', '\u1ee3'), ('\u1ee5', '\u1ee5'), ('\u1ee7',
+ '\u1ee7'), ('\u1ee9', '\u1ee9'), ('\u1eeb', '\u1eeb'), ('\u1eed', '\u1eed'), ('\u1eef',
+ '\u1eef'), ('\u1ef1', '\u1ef1'), ('\u1ef3', '\u1ef3'), ('\u1ef5', '\u1ef5'), ('\u1ef7',
+ '\u1ef7'), ('\u1ef9', '\u1ef9'), ('\u1efb', '\u1efb'), ('\u1efd', '\u1efd'), ('\u1eff',
+ '\u1f07'), ('\u1f10', '\u1f15'), ('\u1f20', '\u1f27'), ('\u1f30', '\u1f37'), ('\u1f40',
+ '\u1f45'), ('\u1f50', '\u1f57'), ('\u1f60', '\u1f67'), ('\u1f70', '\u1f7d'), ('\u1f80',
+ '\u1f87'), ('\u1f90', '\u1f97'), ('\u1fa0', '\u1fa7'), ('\u1fb0', '\u1fb4'), ('\u1fb6',
+ '\u1fb7'), ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fc7'), ('\u1fd0',
+ '\u1fd3'), ('\u1fd6', '\u1fd7'), ('\u1fe0', '\u1fe7'), ('\u1ff2', '\u1ff4'), ('\u1ff6',
+ '\u1ff7'), ('\u210a', '\u210a'), ('\u210e', '\u210f'), ('\u2113', '\u2113'), ('\u212f',
+ '\u212f'), ('\u2134', '\u2134'), ('\u2139', '\u2139'), ('\u213c', '\u213d'), ('\u2146',
+ '\u2149'), ('\u214e', '\u214e'), ('\u2184', '\u2184'), ('\u2c30', '\u2c5e'), ('\u2c61',
+ '\u2c61'), ('\u2c65', '\u2c66'), ('\u2c68', '\u2c68'), ('\u2c6a', '\u2c6a'), ('\u2c6c',
+ '\u2c6c'), ('\u2c71', '\u2c71'), ('\u2c73', '\u2c74'), ('\u2c76', '\u2c7b'), ('\u2c81',
+ '\u2c81'), ('\u2c83', '\u2c83'), ('\u2c85', '\u2c85'), ('\u2c87', '\u2c87'), ('\u2c89',
+ '\u2c89'), ('\u2c8b', '\u2c8b'), ('\u2c8d', '\u2c8d'), ('\u2c8f', '\u2c8f'), ('\u2c91',
+ '\u2c91'), ('\u2c93', '\u2c93'), ('\u2c95', '\u2c95'), ('\u2c97', '\u2c97'), ('\u2c99',
+ '\u2c99'), ('\u2c9b', '\u2c9b'), ('\u2c9d', '\u2c9d'), ('\u2c9f', '\u2c9f'), ('\u2ca1',
+ '\u2ca1'), ('\u2ca3', '\u2ca3'), ('\u2ca5', '\u2ca5'), ('\u2ca7', '\u2ca7'), ('\u2ca9',
+ '\u2ca9'), ('\u2cab', '\u2cab'), ('\u2cad', '\u2cad'), ('\u2caf', '\u2caf'), ('\u2cb1',
+ '\u2cb1'), ('\u2cb3', '\u2cb3'), ('\u2cb5', '\u2cb5'), ('\u2cb7', '\u2cb7'), ('\u2cb9',
+ '\u2cb9'), ('\u2cbb', '\u2cbb'), ('\u2cbd', '\u2cbd'), ('\u2cbf', '\u2cbf'), ('\u2cc1',
+ '\u2cc1'), ('\u2cc3', '\u2cc3'), ('\u2cc5', '\u2cc5'), ('\u2cc7', '\u2cc7'), ('\u2cc9',
+ '\u2cc9'), ('\u2ccb', '\u2ccb'), ('\u2ccd', '\u2ccd'), ('\u2ccf', '\u2ccf'), ('\u2cd1',
+ '\u2cd1'), ('\u2cd3', '\u2cd3'), ('\u2cd5', '\u2cd5'), ('\u2cd7', '\u2cd7'), ('\u2cd9',
+ '\u2cd9'), ('\u2cdb', '\u2cdb'), ('\u2cdd', '\u2cdd'), ('\u2cdf', '\u2cdf'), ('\u2ce1',
+ '\u2ce1'), ('\u2ce3', '\u2ce4'), ('\u2cec', '\u2cec'), ('\u2cee', '\u2cee'), ('\u2cf3',
+ '\u2cf3'), ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'), ('\ua641',
+ '\ua641'), ('\ua643', '\ua643'), ('\ua645', '\ua645'), ('\ua647', '\ua647'), ('\ua649',
+ '\ua649'), ('\ua64b', '\ua64b'), ('\ua64d', '\ua64d'), ('\ua64f', '\ua64f'), ('\ua651',
+ '\ua651'), ('\ua653', '\ua653'), ('\ua655', '\ua655'), ('\ua657', '\ua657'), ('\ua659',
+ '\ua659'), ('\ua65b', '\ua65b'), ('\ua65d', '\ua65d'), ('\ua65f', '\ua65f'), ('\ua661',
+ '\ua661'), ('\ua663', '\ua663'), ('\ua665', '\ua665'), ('\ua667', '\ua667'), ('\ua669',
+ '\ua669'), ('\ua66b', '\ua66b'), ('\ua66d', '\ua66d'), ('\ua681', '\ua681'), ('\ua683',
+ '\ua683'), ('\ua685', '\ua685'), ('\ua687', '\ua687'), ('\ua689', '\ua689'), ('\ua68b',
+ '\ua68b'), ('\ua68d', '\ua68d'), ('\ua68f', '\ua68f'), ('\ua691', '\ua691'), ('\ua693',
+ '\ua693'), ('\ua695', '\ua695'), ('\ua697', '\ua697'), ('\ua699', '\ua699'), ('\ua69b',
+ '\ua69b'), ('\ua723', '\ua723'), ('\ua725', '\ua725'), ('\ua727', '\ua727'), ('\ua729',
+ '\ua729'), ('\ua72b', '\ua72b'), ('\ua72d', '\ua72d'), ('\ua72f', '\ua731'), ('\ua733',
+ '\ua733'), ('\ua735', '\ua735'), ('\ua737', '\ua737'), ('\ua739', '\ua739'), ('\ua73b',
+ '\ua73b'), ('\ua73d', '\ua73d'), ('\ua73f', '\ua73f'), ('\ua741', '\ua741'), ('\ua743',
+ '\ua743'), ('\ua745', '\ua745'), ('\ua747', '\ua747'), ('\ua749', '\ua749'), ('\ua74b',
+ '\ua74b'), ('\ua74d', '\ua74d'), ('\ua74f', '\ua74f'), ('\ua751', '\ua751'), ('\ua753',
+ '\ua753'), ('\ua755', '\ua755'), ('\ua757', '\ua757'), ('\ua759', '\ua759'), ('\ua75b',
+ '\ua75b'), ('\ua75d', '\ua75d'), ('\ua75f', '\ua75f'), ('\ua761', '\ua761'), ('\ua763',
+ '\ua763'), ('\ua765', '\ua765'), ('\ua767', '\ua767'), ('\ua769', '\ua769'), ('\ua76b',
+ '\ua76b'), ('\ua76d', '\ua76d'), ('\ua76f', '\ua76f'), ('\ua771', '\ua778'), ('\ua77a',
+ '\ua77a'), ('\ua77c', '\ua77c'), ('\ua77f', '\ua77f'), ('\ua781', '\ua781'), ('\ua783',
+ '\ua783'), ('\ua785', '\ua785'), ('\ua787', '\ua787'), ('\ua78c', '\ua78c'), ('\ua78e',
+ '\ua78e'), ('\ua791', '\ua791'), ('\ua793', '\ua795'), ('\ua797', '\ua797'), ('\ua799',
+ '\ua799'), ('\ua79b', '\ua79b'), ('\ua79d', '\ua79d'), ('\ua79f', '\ua79f'), ('\ua7a1',
+ '\ua7a1'), ('\ua7a3', '\ua7a3'), ('\ua7a5', '\ua7a5'), ('\ua7a7', '\ua7a7'), ('\ua7a9',
+ '\ua7a9'), ('\ua7fa', '\ua7fa'), ('\uab30', '\uab5a'), ('\uab64', '\uab65'), ('\ufb00',
+ '\ufb06'), ('\ufb13', '\ufb17'), ('\uff41', '\uff5a'), ('\U00010428', '\U0001044f'),
+ ('\U000118c0', '\U000118df'), ('\U0001d41a', '\U0001d433'), ('\U0001d44e', '\U0001d454'),
+ ('\U0001d456', '\U0001d467'), ('\U0001d482', '\U0001d49b'), ('\U0001d4b6', '\U0001d4b9'),
+ ('\U0001d4bb', '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d4cf'),
+ ('\U0001d4ea', '\U0001d503'), ('\U0001d51e', '\U0001d537'), ('\U0001d552', '\U0001d56b'),
+ ('\U0001d586', '\U0001d59f'), ('\U0001d5ba', '\U0001d5d3'), ('\U0001d5ee', '\U0001d607'),
+ ('\U0001d622', '\U0001d63b'), ('\U0001d656', '\U0001d66f'), ('\U0001d68a', '\U0001d6a5'),
+ ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6e1'), ('\U0001d6fc', '\U0001d714'),
+ ('\U0001d716', '\U0001d71b'), ('\U0001d736', '\U0001d74e'), ('\U0001d750', '\U0001d755'),
+ ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d78f'), ('\U0001d7aa', '\U0001d7c2'),
+ ('\U0001d7c4', '\U0001d7c9'), ('\U0001d7cb', '\U0001d7cb')
+ ];
+
+ pub static Lm_table: &'static [(char, char)] = &[
+ ('\u02b0', '\u02c1'), ('\u02c6', '\u02d1'), ('\u02e0', '\u02e4'), ('\u02ec', '\u02ec'),
+ ('\u02ee', '\u02ee'), ('\u0374', '\u0374'), ('\u037a', '\u037a'), ('\u0559', '\u0559'),
+ ('\u0640', '\u0640'), ('\u06e5', '\u06e6'), ('\u07f4', '\u07f5'), ('\u07fa', '\u07fa'),
+ ('\u081a', '\u081a'), ('\u0824', '\u0824'), ('\u0828', '\u0828'), ('\u0971', '\u0971'),
+ ('\u0e46', '\u0e46'), ('\u0ec6', '\u0ec6'), ('\u10fc', '\u10fc'), ('\u17d7', '\u17d7'),
+ ('\u1843', '\u1843'), ('\u1aa7', '\u1aa7'), ('\u1c78', '\u1c7d'), ('\u1d2c', '\u1d6a'),
+ ('\u1d78', '\u1d78'), ('\u1d9b', '\u1dbf'), ('\u2071', '\u2071'), ('\u207f', '\u207f'),
+ ('\u2090', '\u209c'), ('\u2c7c', '\u2c7d'), ('\u2d6f', '\u2d6f'), ('\u2e2f', '\u2e2f'),
+ ('\u3005', '\u3005'), ('\u3031', '\u3035'), ('\u303b', '\u303b'), ('\u309d', '\u309e'),
+ ('\u30fc', '\u30fe'), ('\ua015', '\ua015'), ('\ua4f8', '\ua4fd'), ('\ua60c', '\ua60c'),
+ ('\ua67f', '\ua67f'), ('\ua69c', '\ua69d'), ('\ua717', '\ua71f'), ('\ua770', '\ua770'),
+ ('\ua788', '\ua788'), ('\ua7f8', '\ua7f9'), ('\ua9cf', '\ua9cf'), ('\ua9e6', '\ua9e6'),
+ ('\uaa70', '\uaa70'), ('\uaadd', '\uaadd'), ('\uaaf3', '\uaaf4'), ('\uab5c', '\uab5f'),
+ ('\uff70', '\uff70'), ('\uff9e', '\uff9f'), ('\U00016b40', '\U00016b43'), ('\U00016f93',
+ '\U00016f9f')
+ ];
+
+ pub static Lo_table: &'static [(char, char)] = &[
+ ('\xaa', '\xaa'), ('\xba', '\xba'), ('\u01bb', '\u01bb'), ('\u01c0', '\u01c3'), ('\u0294',
+ '\u0294'), ('\u05d0', '\u05ea'), ('\u05f0', '\u05f2'), ('\u0620', '\u063f'), ('\u0641',
+ '\u064a'), ('\u066e', '\u066f'), ('\u0671', '\u06d3'), ('\u06d5', '\u06d5'), ('\u06ee',
+ '\u06ef'), ('\u06fa', '\u06fc'), ('\u06ff', '\u06ff'), ('\u0710', '\u0710'), ('\u0712',
+ '\u072f'), ('\u074d', '\u07a5'), ('\u07b1', '\u07b1'), ('\u07ca', '\u07ea'), ('\u0800',
+ '\u0815'), ('\u0840', '\u0858'), ('\u08a0', '\u08b2'), ('\u0904', '\u0939'), ('\u093d',
+ '\u093d'), ('\u0950', '\u0950'), ('\u0958', '\u0961'), ('\u0972', '\u0980'), ('\u0985',
+ '\u098c'), ('\u098f', '\u0990'), ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'), ('\u09b2',
+ '\u09b2'), ('\u09b6', '\u09b9'), ('\u09bd', '\u09bd'), ('\u09ce', '\u09ce'), ('\u09dc',
+ '\u09dd'), ('\u09df', '\u09e1'), ('\u09f0', '\u09f1'), ('\u0a05', '\u0a0a'), ('\u0a0f',
+ '\u0a10'), ('\u0a13', '\u0a28'), ('\u0a2a', '\u0a30'), ('\u0a32', '\u0a33'), ('\u0a35',
+ '\u0a36'), ('\u0a38', '\u0a39'), ('\u0a59', '\u0a5c'), ('\u0a5e', '\u0a5e'), ('\u0a72',
+ '\u0a74'), ('\u0a85', '\u0a8d'), ('\u0a8f', '\u0a91'), ('\u0a93', '\u0aa8'), ('\u0aaa',
+ '\u0ab0'), ('\u0ab2', '\u0ab3'), ('\u0ab5', '\u0ab9'), ('\u0abd', '\u0abd'), ('\u0ad0',
+ '\u0ad0'), ('\u0ae0', '\u0ae1'), ('\u0b05', '\u0b0c'), ('\u0b0f', '\u0b10'), ('\u0b13',
+ '\u0b28'), ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'), ('\u0b35', '\u0b39'), ('\u0b3d',
+ '\u0b3d'), ('\u0b5c', '\u0b5d'), ('\u0b5f', '\u0b61'), ('\u0b71', '\u0b71'), ('\u0b83',
+ '\u0b83'), ('\u0b85', '\u0b8a'), ('\u0b8e', '\u0b90'), ('\u0b92', '\u0b95'), ('\u0b99',
+ '\u0b9a'), ('\u0b9c', '\u0b9c'), ('\u0b9e', '\u0b9f'), ('\u0ba3', '\u0ba4'), ('\u0ba8',
+ '\u0baa'), ('\u0bae', '\u0bb9'), ('\u0bd0', '\u0bd0'), ('\u0c05', '\u0c0c'), ('\u0c0e',
+ '\u0c10'), ('\u0c12', '\u0c28'), ('\u0c2a', '\u0c39'), ('\u0c3d', '\u0c3d'), ('\u0c58',
+ '\u0c59'), ('\u0c60', '\u0c61'), ('\u0c85', '\u0c8c'), ('\u0c8e', '\u0c90'), ('\u0c92',
+ '\u0ca8'), ('\u0caa', '\u0cb3'), ('\u0cb5', '\u0cb9'), ('\u0cbd', '\u0cbd'), ('\u0cde',
+ '\u0cde'), ('\u0ce0', '\u0ce1'), ('\u0cf1', '\u0cf2'), ('\u0d05', '\u0d0c'), ('\u0d0e',
+ '\u0d10'), ('\u0d12', '\u0d3a'), ('\u0d3d', '\u0d3d'), ('\u0d4e', '\u0d4e'), ('\u0d60',
+ '\u0d61'), ('\u0d7a', '\u0d7f'), ('\u0d85', '\u0d96'), ('\u0d9a', '\u0db1'), ('\u0db3',
+ '\u0dbb'), ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'), ('\u0e01', '\u0e30'), ('\u0e32',
+ '\u0e33'), ('\u0e40', '\u0e45'), ('\u0e81', '\u0e82'), ('\u0e84', '\u0e84'), ('\u0e87',
+ '\u0e88'), ('\u0e8a', '\u0e8a'), ('\u0e8d', '\u0e8d'), ('\u0e94', '\u0e97'), ('\u0e99',
+ '\u0e9f'), ('\u0ea1', '\u0ea3'), ('\u0ea5', '\u0ea5'), ('\u0ea7', '\u0ea7'), ('\u0eaa',
+ '\u0eab'), ('\u0ead', '\u0eb0'), ('\u0eb2', '\u0eb3'), ('\u0ebd', '\u0ebd'), ('\u0ec0',
+ '\u0ec4'), ('\u0edc', '\u0edf'), ('\u0f00', '\u0f00'), ('\u0f40', '\u0f47'), ('\u0f49',
+ '\u0f6c'), ('\u0f88', '\u0f8c'), ('\u1000', '\u102a'), ('\u103f', '\u103f'), ('\u1050',
+ '\u1055'), ('\u105a', '\u105d'), ('\u1061', '\u1061'), ('\u1065', '\u1066'), ('\u106e',
+ '\u1070'), ('\u1075', '\u1081'), ('\u108e', '\u108e'), ('\u10d0', '\u10fa'), ('\u10fd',
+ '\u1248'), ('\u124a', '\u124d'), ('\u1250', '\u1256'), ('\u1258', '\u1258'), ('\u125a',
+ '\u125d'), ('\u1260', '\u1288'), ('\u128a', '\u128d'), ('\u1290', '\u12b0'), ('\u12b2',
+ '\u12b5'), ('\u12b8', '\u12be'), ('\u12c0', '\u12c0'), ('\u12c2', '\u12c5'), ('\u12c8',
+ '\u12d6'), ('\u12d8', '\u1310'), ('\u1312', '\u1315'), ('\u1318', '\u135a'), ('\u1380',
+ '\u138f'), ('\u13a0', '\u13f4'), ('\u1401', '\u166c'), ('\u166f', '\u167f'), ('\u1681',
+ '\u169a'), ('\u16a0', '\u16ea'), ('\u16f1', '\u16f8'), ('\u1700', '\u170c'), ('\u170e',
+ '\u1711'), ('\u1720', '\u1731'), ('\u1740', '\u1751'), ('\u1760', '\u176c'), ('\u176e',
+ '\u1770'), ('\u1780', '\u17b3'), ('\u17dc', '\u17dc'), ('\u1820', '\u1842'), ('\u1844',
+ '\u1877'), ('\u1880', '\u18a8'), ('\u18aa', '\u18aa'), ('\u18b0', '\u18f5'), ('\u1900',
+ '\u191e'), ('\u1950', '\u196d'), ('\u1970', '\u1974'), ('\u1980', '\u19ab'), ('\u19c1',
+ '\u19c7'), ('\u1a00', '\u1a16'), ('\u1a20', '\u1a54'), ('\u1b05', '\u1b33'), ('\u1b45',
+ '\u1b4b'), ('\u1b83', '\u1ba0'), ('\u1bae', '\u1baf'), ('\u1bba', '\u1be5'), ('\u1c00',
+ '\u1c23'), ('\u1c4d', '\u1c4f'), ('\u1c5a', '\u1c77'), ('\u1ce9', '\u1cec'), ('\u1cee',
+ '\u1cf1'), ('\u1cf5', '\u1cf6'), ('\u2135', '\u2138'), ('\u2d30', '\u2d67'), ('\u2d80',
+ '\u2d96'), ('\u2da0', '\u2da6'), ('\u2da8', '\u2dae'), ('\u2db0', '\u2db6'), ('\u2db8',
+ '\u2dbe'), ('\u2dc0', '\u2dc6'), ('\u2dc8', '\u2dce'), ('\u2dd0', '\u2dd6'), ('\u2dd8',
+ '\u2dde'), ('\u3006', '\u3006'), ('\u303c', '\u303c'), ('\u3041', '\u3096'), ('\u309f',
+ '\u309f'), ('\u30a1', '\u30fa'), ('\u30ff', '\u30ff'), ('\u3105', '\u312d'), ('\u3131',
+ '\u318e'), ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'), ('\u3400', '\u3400'), ('\u4db5',
+ '\u4db5'), ('\u4e00', '\u4e00'), ('\u9fcc', '\u9fcc'), ('\ua000', '\ua014'), ('\ua016',
+ '\ua48c'), ('\ua4d0', '\ua4f7'), ('\ua500', '\ua60b'), ('\ua610', '\ua61f'), ('\ua62a',
+ '\ua62b'), ('\ua66e', '\ua66e'), ('\ua6a0', '\ua6e5'), ('\ua7f7', '\ua7f7'), ('\ua7fb',
+ '\ua801'), ('\ua803', '\ua805'), ('\ua807', '\ua80a'), ('\ua80c', '\ua822'), ('\ua840',
+ '\ua873'), ('\ua882', '\ua8b3'), ('\ua8f2', '\ua8f7'), ('\ua8fb', '\ua8fb'), ('\ua90a',
+ '\ua925'), ('\ua930', '\ua946'), ('\ua960', '\ua97c'), ('\ua984', '\ua9b2'), ('\ua9e0',
+ '\ua9e4'), ('\ua9e7', '\ua9ef'), ('\ua9fa', '\ua9fe'), ('\uaa00', '\uaa28'), ('\uaa40',
+ '\uaa42'), ('\uaa44', '\uaa4b'), ('\uaa60', '\uaa6f'), ('\uaa71', '\uaa76'), ('\uaa7a',
+ '\uaa7a'), ('\uaa7e', '\uaaaf'), ('\uaab1', '\uaab1'), ('\uaab5', '\uaab6'), ('\uaab9',
+ '\uaabd'), ('\uaac0', '\uaac0'), ('\uaac2', '\uaac2'), ('\uaadb', '\uaadc'), ('\uaae0',
+ '\uaaea'), ('\uaaf2', '\uaaf2'), ('\uab01', '\uab06'), ('\uab09', '\uab0e'), ('\uab11',
+ '\uab16'), ('\uab20', '\uab26'), ('\uab28', '\uab2e'), ('\uabc0', '\uabe2'), ('\uac00',
+ '\uac00'), ('\ud7a3', '\ud7a3'), ('\ud7b0', '\ud7c6'), ('\ud7cb', '\ud7fb'), ('\uf900',
+ '\ufa6d'), ('\ufa70', '\ufad9'), ('\ufb1d', '\ufb1d'), ('\ufb1f', '\ufb28'), ('\ufb2a',
+ '\ufb36'), ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'), ('\ufb40', '\ufb41'), ('\ufb43',
+ '\ufb44'), ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufd3d'), ('\ufd50', '\ufd8f'), ('\ufd92',
+ '\ufdc7'), ('\ufdf0', '\ufdfb'), ('\ufe70', '\ufe74'), ('\ufe76', '\ufefc'), ('\uff66',
+ '\uff6f'), ('\uff71', '\uff9d'), ('\uffa0', '\uffbe'), ('\uffc2', '\uffc7'), ('\uffca',
+ '\uffcf'), ('\uffd2', '\uffd7'), ('\uffda', '\uffdc'), ('\U00010000', '\U0001000b'),
+ ('\U0001000d', '\U00010026'), ('\U00010028', '\U0001003a'), ('\U0001003c', '\U0001003d'),
+ ('\U0001003f', '\U0001004d'), ('\U00010050', '\U0001005d'), ('\U00010080', '\U000100fa'),
+ ('\U00010280', '\U0001029c'), ('\U000102a0', '\U000102d0'), ('\U00010300', '\U0001031f'),
+ ('\U00010330', '\U00010340'), ('\U00010342', '\U00010349'), ('\U00010350', '\U00010375'),
+ ('\U00010380', '\U0001039d'), ('\U000103a0', '\U000103c3'), ('\U000103c8', '\U000103cf'),
+ ('\U00010450', '\U0001049d'), ('\U00010500', '\U00010527'), ('\U00010530', '\U00010563'),
+ ('\U00010600', '\U00010736'), ('\U00010740', '\U00010755'), ('\U00010760', '\U00010767'),
+ ('\U00010800', '\U00010805'), ('\U00010808', '\U00010808'), ('\U0001080a', '\U00010835'),
+ ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'), ('\U0001083f', '\U00010855'),
+ ('\U00010860', '\U00010876'), ('\U00010880', '\U0001089e'), ('\U00010900', '\U00010915'),
+ ('\U00010920', '\U00010939'), ('\U00010980', '\U000109b7'), ('\U000109be', '\U000109bf'),
+ ('\U00010a00', '\U00010a00'), ('\U00010a10', '\U00010a13'), ('\U00010a15', '\U00010a17'),
+ ('\U00010a19', '\U00010a33'), ('\U00010a60', '\U00010a7c'), ('\U00010a80', '\U00010a9c'),
+ ('\U00010ac0', '\U00010ac7'), ('\U00010ac9', '\U00010ae4'), ('\U00010b00', '\U00010b35'),
+ ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'), ('\U00010b80', '\U00010b91'),
+ ('\U00010c00', '\U00010c48'), ('\U00011003', '\U00011037'), ('\U00011083', '\U000110af'),
+ ('\U000110d0', '\U000110e8'), ('\U00011103', '\U00011126'), ('\U00011150', '\U00011172'),
+ ('\U00011176', '\U00011176'), ('\U00011183', '\U000111b2'), ('\U000111c1', '\U000111c4'),
+ ('\U000111da', '\U000111da'), ('\U00011200', '\U00011211'), ('\U00011213', '\U0001122b'),
+ ('\U000112b0', '\U000112de'), ('\U00011305', '\U0001130c'), ('\U0001130f', '\U00011310'),
+ ('\U00011313', '\U00011328'), ('\U0001132a', '\U00011330'), ('\U00011332', '\U00011333'),
+ ('\U00011335', '\U00011339'), ('\U0001133d', '\U0001133d'), ('\U0001135d', '\U00011361'),
+ ('\U00011480', '\U000114af'), ('\U000114c4', '\U000114c5'), ('\U000114c7', '\U000114c7'),
+ ('\U00011580', '\U000115ae'), ('\U00011600', '\U0001162f'), ('\U00011644', '\U00011644'),
+ ('\U00011680', '\U000116aa'), ('\U000118ff', '\U000118ff'), ('\U00011ac0', '\U00011af8'),
+ ('\U00012000', '\U00012398'), ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'),
+ ('\U00016a40', '\U00016a5e'), ('\U00016ad0', '\U00016aed'), ('\U00016b00', '\U00016b2f'),
+ ('\U00016b63', '\U00016b77'), ('\U00016b7d', '\U00016b8f'), ('\U00016f00', '\U00016f44'),
+ ('\U00016f50', '\U00016f50'), ('\U0001b000', '\U0001b001'), ('\U0001bc00', '\U0001bc6a'),
+ ('\U0001bc70', '\U0001bc7c'), ('\U0001bc80', '\U0001bc88'), ('\U0001bc90', '\U0001bc99'),
+ ('\U0001e800', '\U0001e8c4'), ('\U0001ee00', '\U0001ee03'), ('\U0001ee05', '\U0001ee1f'),
+ ('\U0001ee21', '\U0001ee22'), ('\U0001ee24', '\U0001ee24'), ('\U0001ee27', '\U0001ee27'),
+ ('\U0001ee29', '\U0001ee32'), ('\U0001ee34', '\U0001ee37'), ('\U0001ee39', '\U0001ee39'),
+ ('\U0001ee3b', '\U0001ee3b'), ('\U0001ee42', '\U0001ee42'), ('\U0001ee47', '\U0001ee47'),
+ ('\U0001ee49', '\U0001ee49'), ('\U0001ee4b', '\U0001ee4b'), ('\U0001ee4d', '\U0001ee4f'),
+ ('\U0001ee51', '\U0001ee52'), ('\U0001ee54', '\U0001ee54'), ('\U0001ee57', '\U0001ee57'),
+ ('\U0001ee59', '\U0001ee59'), ('\U0001ee5b', '\U0001ee5b'), ('\U0001ee5d', '\U0001ee5d'),
+ ('\U0001ee5f', '\U0001ee5f'), ('\U0001ee61', '\U0001ee62'), ('\U0001ee64', '\U0001ee64'),
+ ('\U0001ee67', '\U0001ee6a'), ('\U0001ee6c', '\U0001ee72'), ('\U0001ee74', '\U0001ee77'),
+ ('\U0001ee79', '\U0001ee7c'), ('\U0001ee7e', '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'),
+ ('\U0001ee8b', '\U0001ee9b'), ('\U0001eea1', '\U0001eea3'), ('\U0001eea5', '\U0001eea9'),
+ ('\U0001eeab', '\U0001eebb'), ('\U00020000', '\U00020000'), ('\U0002a6d6', '\U0002a6d6'),
+ ('\U0002a700', '\U0002a700'), ('\U0002b734', '\U0002b734'), ('\U0002b740', '\U0002b740'),
+ ('\U0002b81d', '\U0002b81d'), ('\U0002f800', '\U0002fa1d')
+ ];
+
+ pub static Lt_table: &'static [(char, char)] = &[
+ ('\u01c5', '\u01c5'), ('\u01c8', '\u01c8'), ('\u01cb', '\u01cb'), ('\u01f2', '\u01f2'),
+ ('\u1f88', '\u1f8f'), ('\u1f98', '\u1f9f'), ('\u1fa8', '\u1faf'), ('\u1fbc', '\u1fbc'),
+ ('\u1fcc', '\u1fcc'), ('\u1ffc', '\u1ffc')
+ ];
+
+ pub static Lu_table: &'static [(char, char)] = &[
+ ('\x41', '\x5a'), ('\xc0', '\xd6'), ('\xd8', '\xde'), ('\u0100', '\u0100'), ('\u0102',
+ '\u0102'), ('\u0104', '\u0104'), ('\u0106', '\u0106'), ('\u0108', '\u0108'), ('\u010a',
+ '\u010a'), ('\u010c', '\u010c'), ('\u010e', '\u010e'), ('\u0110', '\u0110'), ('\u0112',
+ '\u0112'), ('\u0114', '\u0114'), ('\u0116', '\u0116'), ('\u0118', '\u0118'), ('\u011a',
+ '\u011a'), ('\u011c', '\u011c'), ('\u011e', '\u011e'), ('\u0120', '\u0120'), ('\u0122',
+ '\u0122'), ('\u0124', '\u0124'), ('\u0126', '\u0126'), ('\u0128', '\u0128'), ('\u012a',
+ '\u012a'), ('\u012c', '\u012c'), ('\u012e', '\u012e'), ('\u0130', '\u0130'), ('\u0132',
+ '\u0132'), ('\u0134', '\u0134'), ('\u0136', '\u0136'), ('\u0139', '\u0139'), ('\u013b',
+ '\u013b'), ('\u013d', '\u013d'), ('\u013f', '\u013f'), ('\u0141', '\u0141'), ('\u0143',
+ '\u0143'), ('\u0145', '\u0145'), ('\u0147', '\u0147'), ('\u014a', '\u014a'), ('\u014c',
+ '\u014c'), ('\u014e', '\u014e'), ('\u0150', '\u0150'), ('\u0152', '\u0152'), ('\u0154',
+ '\u0154'), ('\u0156', '\u0156'), ('\u0158', '\u0158'), ('\u015a', '\u015a'), ('\u015c',
+ '\u015c'), ('\u015e', '\u015e'), ('\u0160', '\u0160'), ('\u0162', '\u0162'), ('\u0164',
+ '\u0164'), ('\u0166', '\u0166'), ('\u0168', '\u0168'), ('\u016a', '\u016a'), ('\u016c',
+ '\u016c'), ('\u016e', '\u016e'), ('\u0170', '\u0170'), ('\u0172', '\u0172'), ('\u0174',
+ '\u0174'), ('\u0176', '\u0176'), ('\u0178', '\u0179'), ('\u017b', '\u017b'), ('\u017d',
+ '\u017d'), ('\u0181', '\u0182'), ('\u0184', '\u0184'), ('\u0186', '\u0187'), ('\u0189',
+ '\u018b'), ('\u018e', '\u0191'), ('\u0193', '\u0194'), ('\u0196', '\u0198'), ('\u019c',
+ '\u019d'), ('\u019f', '\u01a0'), ('\u01a2', '\u01a2'), ('\u01a4', '\u01a4'), ('\u01a6',
+ '\u01a7'), ('\u01a9', '\u01a9'), ('\u01ac', '\u01ac'), ('\u01ae', '\u01af'), ('\u01b1',
+ '\u01b3'), ('\u01b5', '\u01b5'), ('\u01b7', '\u01b8'), ('\u01bc', '\u01bc'), ('\u01c4',
+ '\u01c4'), ('\u01c7', '\u01c7'), ('\u01ca', '\u01ca'), ('\u01cd', '\u01cd'), ('\u01cf',
+ '\u01cf'), ('\u01d1', '\u01d1'), ('\u01d3', '\u01d3'), ('\u01d5', '\u01d5'), ('\u01d7',
+ '\u01d7'), ('\u01d9', '\u01d9'), ('\u01db', '\u01db'), ('\u01de', '\u01de'), ('\u01e0',
+ '\u01e0'), ('\u01e2', '\u01e2'), ('\u01e4', '\u01e4'), ('\u01e6', '\u01e6'), ('\u01e8',
+ '\u01e8'), ('\u01ea', '\u01ea'), ('\u01ec', '\u01ec'), ('\u01ee', '\u01ee'), ('\u01f1',
+ '\u01f1'), ('\u01f4', '\u01f4'), ('\u01f6', '\u01f8'), ('\u01fa', '\u01fa'), ('\u01fc',
+ '\u01fc'), ('\u01fe', '\u01fe'), ('\u0200', '\u0200'), ('\u0202', '\u0202'), ('\u0204',
+ '\u0204'), ('\u0206', '\u0206'), ('\u0208', '\u0208'), ('\u020a', '\u020a'), ('\u020c',
+ '\u020c'), ('\u020e', '\u020e'), ('\u0210', '\u0210'), ('\u0212', '\u0212'), ('\u0214',
+ '\u0214'), ('\u0216', '\u0216'), ('\u0218', '\u0218'), ('\u021a', '\u021a'), ('\u021c',
+ '\u021c'), ('\u021e', '\u021e'), ('\u0220', '\u0220'), ('\u0222', '\u0222'), ('\u0224',
+ '\u0224'), ('\u0226', '\u0226'), ('\u0228', '\u0228'), ('\u022a', '\u022a'), ('\u022c',
+ '\u022c'), ('\u022e', '\u022e'), ('\u0230', '\u0230'), ('\u0232', '\u0232'), ('\u023a',
+ '\u023b'), ('\u023d', '\u023e'), ('\u0241', '\u0241'), ('\u0243', '\u0246'), ('\u0248',
+ '\u0248'), ('\u024a', '\u024a'), ('\u024c', '\u024c'), ('\u024e', '\u024e'), ('\u0370',
+ '\u0370'), ('\u0372', '\u0372'), ('\u0376', '\u0376'), ('\u037f', '\u037f'), ('\u0386',
+ '\u0386'), ('\u0388', '\u038a'), ('\u038c', '\u038c'), ('\u038e', '\u038f'), ('\u0391',
+ '\u03a1'), ('\u03a3', '\u03ab'), ('\u03cf', '\u03cf'), ('\u03d2', '\u03d4'), ('\u03d8',
+ '\u03d8'), ('\u03da', '\u03da'), ('\u03dc', '\u03dc'), ('\u03de', '\u03de'), ('\u03e0',
+ '\u03e0'), ('\u03e2', '\u03e2'), ('\u03e4', '\u03e4'), ('\u03e6', '\u03e6'), ('\u03e8',
+ '\u03e8'), ('\u03ea', '\u03ea'), ('\u03ec', '\u03ec'), ('\u03ee', '\u03ee'), ('\u03f4',
+ '\u03f4'), ('\u03f7', '\u03f7'), ('\u03f9', '\u03fa'), ('\u03fd', '\u042f'), ('\u0460',
+ '\u0460'), ('\u0462', '\u0462'), ('\u0464', '\u0464'), ('\u0466', '\u0466'), ('\u0468',
+ '\u0468'), ('\u046a', '\u046a'), ('\u046c', '\u046c'), ('\u046e', '\u046e'), ('\u0470',
+ '\u0470'), ('\u0472', '\u0472'), ('\u0474', '\u0474'), ('\u0476', '\u0476'), ('\u0478',
+ '\u0478'), ('\u047a', '\u047a'), ('\u047c', '\u047c'), ('\u047e', '\u047e'), ('\u0480',
+ '\u0480'), ('\u048a', '\u048a'), ('\u048c', '\u048c'), ('\u048e', '\u048e'), ('\u0490',
+ '\u0490'), ('\u0492', '\u0492'), ('\u0494', '\u0494'), ('\u0496', '\u0496'), ('\u0498',
+ '\u0498'), ('\u049a', '\u049a'), ('\u049c', '\u049c'), ('\u049e', '\u049e'), ('\u04a0',
+ '\u04a0'), ('\u04a2', '\u04a2'), ('\u04a4', '\u04a4'), ('\u04a6', '\u04a6'), ('\u04a8',
+ '\u04a8'), ('\u04aa', '\u04aa'), ('\u04ac', '\u04ac'), ('\u04ae', '\u04ae'), ('\u04b0',
+ '\u04b0'), ('\u04b2', '\u04b2'), ('\u04b4', '\u04b4'), ('\u04b6', '\u04b6'), ('\u04b8',
+ '\u04b8'), ('\u04ba', '\u04ba'), ('\u04bc', '\u04bc'), ('\u04be', '\u04be'), ('\u04c0',
+ '\u04c1'), ('\u04c3', '\u04c3'), ('\u04c5', '\u04c5'), ('\u04c7', '\u04c7'), ('\u04c9',
+ '\u04c9'), ('\u04cb', '\u04cb'), ('\u04cd', '\u04cd'), ('\u04d0', '\u04d0'), ('\u04d2',
+ '\u04d2'), ('\u04d4', '\u04d4'), ('\u04d6', '\u04d6'), ('\u04d8', '\u04d8'), ('\u04da',
+ '\u04da'), ('\u04dc', '\u04dc'), ('\u04de', '\u04de'), ('\u04e0', '\u04e0'), ('\u04e2',
+ '\u04e2'), ('\u04e4', '\u04e4'), ('\u04e6', '\u04e6'), ('\u04e8', '\u04e8'), ('\u04ea',
+ '\u04ea'), ('\u04ec', '\u04ec'), ('\u04ee', '\u04ee'), ('\u04f0', '\u04f0'), ('\u04f2',
+ '\u04f2'), ('\u04f4', '\u04f4'), ('\u04f6', '\u04f6'), ('\u04f8', '\u04f8'), ('\u04fa',
+ '\u04fa'), ('\u04fc', '\u04fc'), ('\u04fe', '\u04fe'), ('\u0500', '\u0500'), ('\u0502',
+ '\u0502'), ('\u0504', '\u0504'), ('\u0506', '\u0506'), ('\u0508', '\u0508'), ('\u050a',
+ '\u050a'), ('\u050c', '\u050c'), ('\u050e', '\u050e'), ('\u0510', '\u0510'), ('\u0512',
+ '\u0512'), ('\u0514', '\u0514'), ('\u0516', '\u0516'), ('\u0518', '\u0518'), ('\u051a',
+ '\u051a'), ('\u051c', '\u051c'), ('\u051e', '\u051e'), ('\u0520', '\u0520'), ('\u0522',
+ '\u0522'), ('\u0524', '\u0524'), ('\u0526', '\u0526'), ('\u0528', '\u0528'), ('\u052a',
+ '\u052a'), ('\u052c', '\u052c'), ('\u052e', '\u052e'), ('\u0531', '\u0556'), ('\u10a0',
+ '\u10c5'), ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'), ('\u1e00', '\u1e00'), ('\u1e02',
+ '\u1e02'), ('\u1e04', '\u1e04'), ('\u1e06', '\u1e06'), ('\u1e08', '\u1e08'), ('\u1e0a',
+ '\u1e0a'), ('\u1e0c', '\u1e0c'), ('\u1e0e', '\u1e0e'), ('\u1e10', '\u1e10'), ('\u1e12',
+ '\u1e12'), ('\u1e14', '\u1e14'), ('\u1e16', '\u1e16'), ('\u1e18', '\u1e18'), ('\u1e1a',
+ '\u1e1a'), ('\u1e1c', '\u1e1c'), ('\u1e1e', '\u1e1e'), ('\u1e20', '\u1e20'), ('\u1e22',
+ '\u1e22'), ('\u1e24', '\u1e24'), ('\u1e26', '\u1e26'), ('\u1e28', '\u1e28'), ('\u1e2a',
+ '\u1e2a'), ('\u1e2c', '\u1e2c'), ('\u1e2e', '\u1e2e'), ('\u1e30', '\u1e30'), ('\u1e32',
+ '\u1e32'), ('\u1e34', '\u1e34'), ('\u1e36', '\u1e36'), ('\u1e38', '\u1e38'), ('\u1e3a',
+ '\u1e3a'), ('\u1e3c', '\u1e3c'), ('\u1e3e', '\u1e3e'), ('\u1e40', '\u1e40'), ('\u1e42',
+ '\u1e42'), ('\u1e44', '\u1e44'), ('\u1e46', '\u1e46'), ('\u1e48', '\u1e48'), ('\u1e4a',
+ '\u1e4a'), ('\u1e4c', '\u1e4c'), ('\u1e4e', '\u1e4e'), ('\u1e50', '\u1e50'), ('\u1e52',
+ '\u1e52'), ('\u1e54', '\u1e54'), ('\u1e56', '\u1e56'), ('\u1e58', '\u1e58'), ('\u1e5a',
+ '\u1e5a'), ('\u1e5c', '\u1e5c'), ('\u1e5e', '\u1e5e'), ('\u1e60', '\u1e60'), ('\u1e62',
+ '\u1e62'), ('\u1e64', '\u1e64'), ('\u1e66', '\u1e66'), ('\u1e68', '\u1e68'), ('\u1e6a',
+ '\u1e6a'), ('\u1e6c', '\u1e6c'), ('\u1e6e', '\u1e6e'), ('\u1e70', '\u1e70'), ('\u1e72',
+ '\u1e72'), ('\u1e74', '\u1e74'), ('\u1e76', '\u1e76'), ('\u1e78', '\u1e78'), ('\u1e7a',
+ '\u1e7a'), ('\u1e7c', '\u1e7c'), ('\u1e7e', '\u1e7e'), ('\u1e80', '\u1e80'), ('\u1e82',
+ '\u1e82'), ('\u1e84', '\u1e84'), ('\u1e86', '\u1e86'), ('\u1e88', '\u1e88'), ('\u1e8a',
+ '\u1e8a'), ('\u1e8c', '\u1e8c'), ('\u1e8e', '\u1e8e'), ('\u1e90', '\u1e90'), ('\u1e92',
+ '\u1e92'), ('\u1e94', '\u1e94'), ('\u1e9e', '\u1e9e'), ('\u1ea0', '\u1ea0'), ('\u1ea2',
+ '\u1ea2'), ('\u1ea4', '\u1ea4'), ('\u1ea6', '\u1ea6'), ('\u1ea8', '\u1ea8'), ('\u1eaa',
+ '\u1eaa'), ('\u1eac', '\u1eac'), ('\u1eae', '\u1eae'), ('\u1eb0', '\u1eb0'), ('\u1eb2',
+ '\u1eb2'), ('\u1eb4', '\u1eb4'), ('\u1eb6', '\u1eb6'), ('\u1eb8', '\u1eb8'), ('\u1eba',
+ '\u1eba'), ('\u1ebc', '\u1ebc'), ('\u1ebe', '\u1ebe'), ('\u1ec0', '\u1ec0'), ('\u1ec2',
+ '\u1ec2'), ('\u1ec4', '\u1ec4'), ('\u1ec6', '\u1ec6'), ('\u1ec8', '\u1ec8'), ('\u1eca',
+ '\u1eca'), ('\u1ecc', '\u1ecc'), ('\u1ece', '\u1ece'), ('\u1ed0', '\u1ed0'), ('\u1ed2',
+ '\u1ed2'), ('\u1ed4', '\u1ed4'), ('\u1ed6', '\u1ed6'), ('\u1ed8', '\u1ed8'), ('\u1eda',
+ '\u1eda'), ('\u1edc', '\u1edc'), ('\u1ede', '\u1ede'), ('\u1ee0', '\u1ee0'), ('\u1ee2',
+ '\u1ee2'), ('\u1ee4', '\u1ee4'), ('\u1ee6', '\u1ee6'), ('\u1ee8', '\u1ee8'), ('\u1eea',
+ '\u1eea'), ('\u1eec', '\u1eec'), ('\u1eee', '\u1eee'), ('\u1ef0', '\u1ef0'), ('\u1ef2',
+ '\u1ef2'), ('\u1ef4', '\u1ef4'), ('\u1ef6', '\u1ef6'), ('\u1ef8', '\u1ef8'), ('\u1efa',
+ '\u1efa'), ('\u1efc', '\u1efc'), ('\u1efe', '\u1efe'), ('\u1f08', '\u1f0f'), ('\u1f18',
+ '\u1f1d'), ('\u1f28', '\u1f2f'), ('\u1f38', '\u1f3f'), ('\u1f48', '\u1f4d'), ('\u1f59',
+ '\u1f59'), ('\u1f5b', '\u1f5b'), ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f5f'), ('\u1f68',
+ '\u1f6f'), ('\u1fb8', '\u1fbb'), ('\u1fc8', '\u1fcb'), ('\u1fd8', '\u1fdb'), ('\u1fe8',
+ '\u1fec'), ('\u1ff8', '\u1ffb'), ('\u2102', '\u2102'), ('\u2107', '\u2107'), ('\u210b',
+ '\u210d'), ('\u2110', '\u2112'), ('\u2115', '\u2115'), ('\u2119', '\u211d'), ('\u2124',
+ '\u2124'), ('\u2126', '\u2126'), ('\u2128', '\u2128'), ('\u212a', '\u212d'), ('\u2130',
+ '\u2133'), ('\u213e', '\u213f'), ('\u2145', '\u2145'), ('\u2183', '\u2183'), ('\u2c00',
+ '\u2c2e'), ('\u2c60', '\u2c60'), ('\u2c62', '\u2c64'), ('\u2c67', '\u2c67'), ('\u2c69',
+ '\u2c69'), ('\u2c6b', '\u2c6b'), ('\u2c6d', '\u2c70'), ('\u2c72', '\u2c72'), ('\u2c75',
+ '\u2c75'), ('\u2c7e', '\u2c80'), ('\u2c82', '\u2c82'), ('\u2c84', '\u2c84'), ('\u2c86',
+ '\u2c86'), ('\u2c88', '\u2c88'), ('\u2c8a', '\u2c8a'), ('\u2c8c', '\u2c8c'), ('\u2c8e',
+ '\u2c8e'), ('\u2c90', '\u2c90'), ('\u2c92', '\u2c92'), ('\u2c94', '\u2c94'), ('\u2c96',
+ '\u2c96'), ('\u2c98', '\u2c98'), ('\u2c9a', '\u2c9a'), ('\u2c9c', '\u2c9c'), ('\u2c9e',
+ '\u2c9e'), ('\u2ca0', '\u2ca0'), ('\u2ca2', '\u2ca2'), ('\u2ca4', '\u2ca4'), ('\u2ca6',
+ '\u2ca6'), ('\u2ca8', '\u2ca8'), ('\u2caa', '\u2caa'), ('\u2cac', '\u2cac'), ('\u2cae',
+ '\u2cae'), ('\u2cb0', '\u2cb0'), ('\u2cb2', '\u2cb2'), ('\u2cb4', '\u2cb4'), ('\u2cb6',
+ '\u2cb6'), ('\u2cb8', '\u2cb8'), ('\u2cba', '\u2cba'), ('\u2cbc', '\u2cbc'), ('\u2cbe',
+ '\u2cbe'), ('\u2cc0', '\u2cc0'), ('\u2cc2', '\u2cc2'), ('\u2cc4', '\u2cc4'), ('\u2cc6',
+ '\u2cc6'), ('\u2cc8', '\u2cc8'), ('\u2cca', '\u2cca'), ('\u2ccc', '\u2ccc'), ('\u2cce',
+ '\u2cce'), ('\u2cd0', '\u2cd0'), ('\u2cd2', '\u2cd2'), ('\u2cd4', '\u2cd4'), ('\u2cd6',
+ '\u2cd6'), ('\u2cd8', '\u2cd8'), ('\u2cda', '\u2cda'), ('\u2cdc', '\u2cdc'), ('\u2cde',
+ '\u2cde'), ('\u2ce0', '\u2ce0'), ('\u2ce2', '\u2ce2'), ('\u2ceb', '\u2ceb'), ('\u2ced',
+ '\u2ced'), ('\u2cf2', '\u2cf2'), ('\ua640', '\ua640'), ('\ua642', '\ua642'), ('\ua644',
+ '\ua644'), ('\ua646', '\ua646'), ('\ua648', '\ua648'), ('\ua64a', '\ua64a'), ('\ua64c',
+ '\ua64c'), ('\ua64e', '\ua64e'), ('\ua650', '\ua650'), ('\ua652', '\ua652'), ('\ua654',
+ '\ua654'), ('\ua656', '\ua656'), ('\ua658', '\ua658'), ('\ua65a', '\ua65a'), ('\ua65c',
+ '\ua65c'), ('\ua65e', '\ua65e'), ('\ua660', '\ua660'), ('\ua662', '\ua662'), ('\ua664',
+ '\ua664'), ('\ua666', '\ua666'), ('\ua668', '\ua668'), ('\ua66a', '\ua66a'), ('\ua66c',
+ '\ua66c'), ('\ua680', '\ua680'), ('\ua682', '\ua682'), ('\ua684', '\ua684'), ('\ua686',
+ '\ua686'), ('\ua688', '\ua688'), ('\ua68a', '\ua68a'), ('\ua68c', '\ua68c'), ('\ua68e',
+ '\ua68e'), ('\ua690', '\ua690'), ('\ua692', '\ua692'), ('\ua694', '\ua694'), ('\ua696',
+ '\ua696'), ('\ua698', '\ua698'), ('\ua69a', '\ua69a'), ('\ua722', '\ua722'), ('\ua724',
+ '\ua724'), ('\ua726', '\ua726'), ('\ua728', '\ua728'), ('\ua72a', '\ua72a'), ('\ua72c',
+ '\ua72c'), ('\ua72e', '\ua72e'), ('\ua732', '\ua732'), ('\ua734', '\ua734'), ('\ua736',
+ '\ua736'), ('\ua738', '\ua738'), ('\ua73a', '\ua73a'), ('\ua73c', '\ua73c'), ('\ua73e',
+ '\ua73e'), ('\ua740', '\ua740'), ('\ua742', '\ua742'), ('\ua744', '\ua744'), ('\ua746',
+ '\ua746'), ('\ua748', '\ua748'), ('\ua74a', '\ua74a'), ('\ua74c', '\ua74c'), ('\ua74e',
+ '\ua74e'), ('\ua750', '\ua750'), ('\ua752', '\ua752'), ('\ua754', '\ua754'), ('\ua756',
+ '\ua756'), ('\ua758', '\ua758'), ('\ua75a', '\ua75a'), ('\ua75c', '\ua75c'), ('\ua75e',
+ '\ua75e'), ('\ua760', '\ua760'), ('\ua762', '\ua762'), ('\ua764', '\ua764'), ('\ua766',
+ '\ua766'), ('\ua768', '\ua768'), ('\ua76a', '\ua76a'), ('\ua76c', '\ua76c'), ('\ua76e',
+ '\ua76e'), ('\ua779', '\ua779'), ('\ua77b', '\ua77b'), ('\ua77d', '\ua77e'), ('\ua780',
+ '\ua780'), ('\ua782', '\ua782'), ('\ua784', '\ua784'), ('\ua786', '\ua786'), ('\ua78b',
+ '\ua78b'), ('\ua78d', '\ua78d'), ('\ua790', '\ua790'), ('\ua792', '\ua792'), ('\ua796',
+ '\ua796'), ('\ua798', '\ua798'), ('\ua79a', '\ua79a'), ('\ua79c', '\ua79c'), ('\ua79e',
+ '\ua79e'), ('\ua7a0', '\ua7a0'), ('\ua7a2', '\ua7a2'), ('\ua7a4', '\ua7a4'), ('\ua7a6',
+ '\ua7a6'), ('\ua7a8', '\ua7a8'), ('\ua7aa', '\ua7ad'), ('\ua7b0', '\ua7b1'), ('\uff21',
+ '\uff3a'), ('\U00010400', '\U00010427'), ('\U000118a0', '\U000118bf'), ('\U0001d400',
+ '\U0001d419'), ('\U0001d434', '\U0001d44d'), ('\U0001d468', '\U0001d481'), ('\U0001d49c',
+ '\U0001d49c'), ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5',
+ '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b5'), ('\U0001d4d0',
+ '\U0001d4e9'), ('\U0001d504', '\U0001d505'), ('\U0001d507', '\U0001d50a'), ('\U0001d50d',
+ '\U0001d514'), ('\U0001d516', '\U0001d51c'), ('\U0001d538', '\U0001d539'), ('\U0001d53b',
+ '\U0001d53e'), ('\U0001d540', '\U0001d544'), ('\U0001d546', '\U0001d546'), ('\U0001d54a',
+ '\U0001d550'), ('\U0001d56c', '\U0001d585'), ('\U0001d5a0', '\U0001d5b9'), ('\U0001d5d4',
+ '\U0001d5ed'), ('\U0001d608', '\U0001d621'), ('\U0001d63c', '\U0001d655'), ('\U0001d670',
+ '\U0001d689'), ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6e2', '\U0001d6fa'), ('\U0001d71c',
+ '\U0001d734'), ('\U0001d756', '\U0001d76e'), ('\U0001d790', '\U0001d7a8'), ('\U0001d7ca',
+ '\U0001d7ca')
+ ];
+
+ pub static M_table: &'static [(char, char)] = &[
+ ('\u0300', '\u036f'), ('\u0483', '\u0489'), ('\u0591', '\u05bd'), ('\u05bf', '\u05bf'),
+ ('\u05c1', '\u05c2'), ('\u05c4', '\u05c5'), ('\u05c7', '\u05c7'), ('\u0610', '\u061a'),
+ ('\u064b', '\u065f'), ('\u0670', '\u0670'), ('\u06d6', '\u06dc'), ('\u06df', '\u06e4'),
+ ('\u06e7', '\u06e8'), ('\u06ea', '\u06ed'), ('\u0711', '\u0711'), ('\u0730', '\u074a'),
+ ('\u07a6', '\u07b0'), ('\u07eb', '\u07f3'), ('\u0816', '\u0819'), ('\u081b', '\u0823'),
+ ('\u0825', '\u0827'), ('\u0829', '\u082d'), ('\u0859', '\u085b'), ('\u08e4', '\u0903'),
+ ('\u093a', '\u093c'), ('\u093e', '\u094f'), ('\u0951', '\u0957'), ('\u0962', '\u0963'),
+ ('\u0981', '\u0983'), ('\u09bc', '\u09bc'), ('\u09be', '\u09c4'), ('\u09c7', '\u09c8'),
+ ('\u09cb', '\u09cd'), ('\u09d7', '\u09d7'), ('\u09e2', '\u09e3'), ('\u0a01', '\u0a03'),
+ ('\u0a3c', '\u0a3c'), ('\u0a3e', '\u0a42'), ('\u0a47', '\u0a48'), ('\u0a4b', '\u0a4d'),
+ ('\u0a51', '\u0a51'), ('\u0a70', '\u0a71'), ('\u0a75', '\u0a75'), ('\u0a81', '\u0a83'),
+ ('\u0abc', '\u0abc'), ('\u0abe', '\u0ac5'), ('\u0ac7', '\u0ac9'), ('\u0acb', '\u0acd'),
+ ('\u0ae2', '\u0ae3'), ('\u0b01', '\u0b03'), ('\u0b3c', '\u0b3c'), ('\u0b3e', '\u0b44'),
+ ('\u0b47', '\u0b48'), ('\u0b4b', '\u0b4d'), ('\u0b56', '\u0b57'), ('\u0b62', '\u0b63'),
+ ('\u0b82', '\u0b82'), ('\u0bbe', '\u0bc2'), ('\u0bc6', '\u0bc8'), ('\u0bca', '\u0bcd'),
+ ('\u0bd7', '\u0bd7'), ('\u0c00', '\u0c03'), ('\u0c3e', '\u0c44'), ('\u0c46', '\u0c48'),
+ ('\u0c4a', '\u0c4d'), ('\u0c55', '\u0c56'), ('\u0c62', '\u0c63'), ('\u0c81', '\u0c83'),
+ ('\u0cbc', '\u0cbc'), ('\u0cbe', '\u0cc4'), ('\u0cc6', '\u0cc8'), ('\u0cca', '\u0ccd'),
+ ('\u0cd5', '\u0cd6'), ('\u0ce2', '\u0ce3'), ('\u0d01', '\u0d03'), ('\u0d3e', '\u0d44'),
+ ('\u0d46', '\u0d48'), ('\u0d4a', '\u0d4d'), ('\u0d57', '\u0d57'), ('\u0d62', '\u0d63'),
+ ('\u0d82', '\u0d83'), ('\u0dca', '\u0dca'), ('\u0dcf', '\u0dd4'), ('\u0dd6', '\u0dd6'),
+ ('\u0dd8', '\u0ddf'), ('\u0df2', '\u0df3'), ('\u0e31', '\u0e31'), ('\u0e34', '\u0e3a'),
+ ('\u0e47', '\u0e4e'), ('\u0eb1', '\u0eb1'), ('\u0eb4', '\u0eb9'), ('\u0ebb', '\u0ebc'),
+ ('\u0ec8', '\u0ecd'), ('\u0f18', '\u0f19'), ('\u0f35', '\u0f35'), ('\u0f37', '\u0f37'),
+ ('\u0f39', '\u0f39'), ('\u0f3e', '\u0f3f'), ('\u0f71', '\u0f84'), ('\u0f86', '\u0f87'),
+ ('\u0f8d', '\u0f97'), ('\u0f99', '\u0fbc'), ('\u0fc6', '\u0fc6'), ('\u102b', '\u103e'),
+ ('\u1056', '\u1059'), ('\u105e', '\u1060'), ('\u1062', '\u1064'), ('\u1067', '\u106d'),
+ ('\u1071', '\u1074'), ('\u1082', '\u108d'), ('\u108f', '\u108f'), ('\u109a', '\u109d'),
+ ('\u135d', '\u135f'), ('\u1712', '\u1714'), ('\u1732', '\u1734'), ('\u1752', '\u1753'),
+ ('\u1772', '\u1773'), ('\u17b4', '\u17d3'), ('\u17dd', '\u17dd'), ('\u180b', '\u180d'),
+ ('\u18a9', '\u18a9'), ('\u1920', '\u192b'), ('\u1930', '\u193b'), ('\u19b0', '\u19c0'),
+ ('\u19c8', '\u19c9'), ('\u1a17', '\u1a1b'), ('\u1a55', '\u1a5e'), ('\u1a60', '\u1a7c'),
+ ('\u1a7f', '\u1a7f'), ('\u1ab0', '\u1abe'), ('\u1b00', '\u1b04'), ('\u1b34', '\u1b44'),
+ ('\u1b6b', '\u1b73'), ('\u1b80', '\u1b82'), ('\u1ba1', '\u1bad'), ('\u1be6', '\u1bf3'),
+ ('\u1c24', '\u1c37'), ('\u1cd0', '\u1cd2'), ('\u1cd4', '\u1ce8'), ('\u1ced', '\u1ced'),
+ ('\u1cf2', '\u1cf4'), ('\u1cf8', '\u1cf9'), ('\u1dc0', '\u1df5'), ('\u1dfc', '\u1dff'),
+ ('\u20d0', '\u20f0'), ('\u2cef', '\u2cf1'), ('\u2d7f', '\u2d7f'), ('\u2de0', '\u2dff'),
+ ('\u302a', '\u302f'), ('\u3099', '\u309a'), ('\ua66f', '\ua672'), ('\ua674', '\ua67d'),
+ ('\ua69f', '\ua69f'), ('\ua6f0', '\ua6f1'), ('\ua802', '\ua802'), ('\ua806', '\ua806'),
+ ('\ua80b', '\ua80b'), ('\ua823', '\ua827'), ('\ua880', '\ua881'), ('\ua8b4', '\ua8c4'),
+ ('\ua8e0', '\ua8f1'), ('\ua926', '\ua92d'), ('\ua947', '\ua953'), ('\ua980', '\ua983'),
+ ('\ua9b3', '\ua9c0'), ('\ua9e5', '\ua9e5'), ('\uaa29', '\uaa36'), ('\uaa43', '\uaa43'),
+ ('\uaa4c', '\uaa4d'), ('\uaa7b', '\uaa7d'), ('\uaab0', '\uaab0'), ('\uaab2', '\uaab4'),
+ ('\uaab7', '\uaab8'), ('\uaabe', '\uaabf'), ('\uaac1', '\uaac1'), ('\uaaeb', '\uaaef'),
+ ('\uaaf5', '\uaaf6'), ('\uabe3', '\uabea'), ('\uabec', '\uabed'), ('\ufb1e', '\ufb1e'),
+ ('\ufe00', '\ufe0f'), ('\ufe20', '\ufe2d'), ('\U000101fd', '\U000101fd'), ('\U000102e0',
+ '\U000102e0'), ('\U00010376', '\U0001037a'), ('\U00010a01', '\U00010a03'), ('\U00010a05',
+ '\U00010a06'), ('\U00010a0c', '\U00010a0f'), ('\U00010a38', '\U00010a3a'), ('\U00010a3f',
+ '\U00010a3f'), ('\U00010ae5', '\U00010ae6'), ('\U00011000', '\U00011002'), ('\U00011038',
+ '\U00011046'), ('\U0001107f', '\U00011082'), ('\U000110b0', '\U000110ba'), ('\U00011100',
+ '\U00011102'), ('\U00011127', '\U00011134'), ('\U00011173', '\U00011173'), ('\U00011180',
+ '\U00011182'), ('\U000111b3', '\U000111c0'), ('\U0001122c', '\U00011237'), ('\U000112df',
+ '\U000112ea'), ('\U00011301', '\U00011303'), ('\U0001133c', '\U0001133c'), ('\U0001133e',
+ '\U00011344'), ('\U00011347', '\U00011348'), ('\U0001134b', '\U0001134d'), ('\U00011357',
+ '\U00011357'), ('\U00011362', '\U00011363'), ('\U00011366', '\U0001136c'), ('\U00011370',
+ '\U00011374'), ('\U000114b0', '\U000114c3'), ('\U000115af', '\U000115b5'), ('\U000115b8',
+ '\U000115c0'), ('\U00011630', '\U00011640'), ('\U000116ab', '\U000116b7'), ('\U00016af0',
+ '\U00016af4'), ('\U00016b30', '\U00016b36'), ('\U00016f51', '\U00016f7e'), ('\U00016f8f',
+ '\U00016f92'), ('\U0001bc9d', '\U0001bc9e'), ('\U0001d165', '\U0001d169'), ('\U0001d16d',
+ '\U0001d172'), ('\U0001d17b', '\U0001d182'), ('\U0001d185', '\U0001d18b'), ('\U0001d1aa',
+ '\U0001d1ad'), ('\U0001d242', '\U0001d244'), ('\U0001e8d0', '\U0001e8d6'), ('\U000e0100',
+ '\U000e01ef')
+ ];
+
+ pub static Mc_table: &'static [(char, char)] = &[
+ ('\u0903', '\u0903'), ('\u093b', '\u093b'), ('\u093e', '\u0940'), ('\u0949', '\u094c'),
+ ('\u094e', '\u094f'), ('\u0982', '\u0983'), ('\u09be', '\u09c0'), ('\u09c7', '\u09c8'),
+ ('\u09cb', '\u09cc'), ('\u09d7', '\u09d7'), ('\u0a03', '\u0a03'), ('\u0a3e', '\u0a40'),
+ ('\u0a83', '\u0a83'), ('\u0abe', '\u0ac0'), ('\u0ac9', '\u0ac9'), ('\u0acb', '\u0acc'),
+ ('\u0b02', '\u0b03'), ('\u0b3e', '\u0b3e'), ('\u0b40', '\u0b40'), ('\u0b47', '\u0b48'),
+ ('\u0b4b', '\u0b4c'), ('\u0b57', '\u0b57'), ('\u0bbe', '\u0bbf'), ('\u0bc1', '\u0bc2'),
+ ('\u0bc6', '\u0bc8'), ('\u0bca', '\u0bcc'), ('\u0bd7', '\u0bd7'), ('\u0c01', '\u0c03'),
+ ('\u0c41', '\u0c44'), ('\u0c82', '\u0c83'), ('\u0cbe', '\u0cbe'), ('\u0cc0', '\u0cc4'),
+ ('\u0cc7', '\u0cc8'), ('\u0cca', '\u0ccb'), ('\u0cd5', '\u0cd6'), ('\u0d02', '\u0d03'),
+ ('\u0d3e', '\u0d40'), ('\u0d46', '\u0d48'), ('\u0d4a', '\u0d4c'), ('\u0d57', '\u0d57'),
+ ('\u0d82', '\u0d83'), ('\u0dcf', '\u0dd1'), ('\u0dd8', '\u0ddf'), ('\u0df2', '\u0df3'),
+ ('\u0f3e', '\u0f3f'), ('\u0f7f', '\u0f7f'), ('\u102b', '\u102c'), ('\u1031', '\u1031'),
+ ('\u1038', '\u1038'), ('\u103b', '\u103c'), ('\u1056', '\u1057'), ('\u1062', '\u1064'),
+ ('\u1067', '\u106d'), ('\u1083', '\u1084'), ('\u1087', '\u108c'), ('\u108f', '\u108f'),
+ ('\u109a', '\u109c'), ('\u17b6', '\u17b6'), ('\u17be', '\u17c5'), ('\u17c7', '\u17c8'),
+ ('\u1923', '\u1926'), ('\u1929', '\u192b'), ('\u1930', '\u1931'), ('\u1933', '\u1938'),
+ ('\u19b0', '\u19c0'), ('\u19c8', '\u19c9'), ('\u1a19', '\u1a1a'), ('\u1a55', '\u1a55'),
+ ('\u1a57', '\u1a57'), ('\u1a61', '\u1a61'), ('\u1a63', '\u1a64'), ('\u1a6d', '\u1a72'),
+ ('\u1b04', '\u1b04'), ('\u1b35', '\u1b35'), ('\u1b3b', '\u1b3b'), ('\u1b3d', '\u1b41'),
+ ('\u1b43', '\u1b44'), ('\u1b82', '\u1b82'), ('\u1ba1', '\u1ba1'), ('\u1ba6', '\u1ba7'),
+ ('\u1baa', '\u1baa'), ('\u1be7', '\u1be7'), ('\u1bea', '\u1bec'), ('\u1bee', '\u1bee'),
+ ('\u1bf2', '\u1bf3'), ('\u1c24', '\u1c2b'), ('\u1c34', '\u1c35'), ('\u1ce1', '\u1ce1'),
+ ('\u1cf2', '\u1cf3'), ('\u302e', '\u302f'), ('\ua823', '\ua824'), ('\ua827', '\ua827'),
+ ('\ua880', '\ua881'), ('\ua8b4', '\ua8c3'), ('\ua952', '\ua953'), ('\ua983', '\ua983'),
+ ('\ua9b4', '\ua9b5'), ('\ua9ba', '\ua9bb'), ('\ua9bd', '\ua9c0'), ('\uaa2f', '\uaa30'),
+ ('\uaa33', '\uaa34'), ('\uaa4d', '\uaa4d'), ('\uaa7b', '\uaa7b'), ('\uaa7d', '\uaa7d'),
+ ('\uaaeb', '\uaaeb'), ('\uaaee', '\uaaef'), ('\uaaf5', '\uaaf5'), ('\uabe3', '\uabe4'),
+ ('\uabe6', '\uabe7'), ('\uabe9', '\uabea'), ('\uabec', '\uabec'), ('\U00011000',
+ '\U00011000'), ('\U00011002', '\U00011002'), ('\U00011082', '\U00011082'), ('\U000110b0',
+ '\U000110b2'), ('\U000110b7', '\U000110b8'), ('\U0001112c', '\U0001112c'), ('\U00011182',
+ '\U00011182'), ('\U000111b3', '\U000111b5'), ('\U000111bf', '\U000111c0'), ('\U0001122c',
+ '\U0001122e'), ('\U00011232', '\U00011233'), ('\U00011235', '\U00011235'), ('\U000112e0',
+ '\U000112e2'), ('\U00011302', '\U00011303'), ('\U0001133e', '\U0001133f'), ('\U00011341',
+ '\U00011344'), ('\U00011347', '\U00011348'), ('\U0001134b', '\U0001134d'), ('\U00011357',
+ '\U00011357'), ('\U00011362', '\U00011363'), ('\U000114b0', '\U000114b2'), ('\U000114b9',
+ '\U000114b9'), ('\U000114bb', '\U000114be'), ('\U000114c1', '\U000114c1'), ('\U000115af',
+ '\U000115b1'), ('\U000115b8', '\U000115bb'), ('\U000115be', '\U000115be'), ('\U00011630',
+ '\U00011632'), ('\U0001163b', '\U0001163c'), ('\U0001163e', '\U0001163e'), ('\U000116ac',
+ '\U000116ac'), ('\U000116ae', '\U000116af'), ('\U000116b6', '\U000116b6'), ('\U00016f51',
+ '\U00016f7e'), ('\U0001d165', '\U0001d166'), ('\U0001d16d', '\U0001d172')
+ ];
+
+ pub static Me_table: &'static [(char, char)] = &[
+ ('\u0488', '\u0489'), ('\u1abe', '\u1abe'), ('\u20dd', '\u20e0'), ('\u20e2', '\u20e4'),
+ ('\ua670', '\ua672')
+ ];
+
+ pub static Mn_table: &'static [(char, char)] = &[
+ ('\u0300', '\u036f'), ('\u0483', '\u0487'), ('\u0591', '\u05bd'), ('\u05bf', '\u05bf'),
+ ('\u05c1', '\u05c2'), ('\u05c4', '\u05c5'), ('\u05c7', '\u05c7'), ('\u0610', '\u061a'),
+ ('\u064b', '\u065f'), ('\u0670', '\u0670'), ('\u06d6', '\u06dc'), ('\u06df', '\u06e4'),
+ ('\u06e7', '\u06e8'), ('\u06ea', '\u06ed'), ('\u0711', '\u0711'), ('\u0730', '\u074a'),
+ ('\u07a6', '\u07b0'), ('\u07eb', '\u07f3'), ('\u0816', '\u0819'), ('\u081b', '\u0823'),
+ ('\u0825', '\u0827'), ('\u0829', '\u082d'), ('\u0859', '\u085b'), ('\u08e4', '\u0902'),
+ ('\u093a', '\u093a'), ('\u093c', '\u093c'), ('\u0941', '\u0948'), ('\u094d', '\u094d'),
+ ('\u0951', '\u0957'), ('\u0962', '\u0963'), ('\u0981', '\u0981'), ('\u09bc', '\u09bc'),
+ ('\u09c1', '\u09c4'), ('\u09cd', '\u09cd'), ('\u09e2', '\u09e3'), ('\u0a01', '\u0a02'),
+ ('\u0a3c', '\u0a3c'), ('\u0a41', '\u0a42'), ('\u0a47', '\u0a48'), ('\u0a4b', '\u0a4d'),
+ ('\u0a51', '\u0a51'), ('\u0a70', '\u0a71'), ('\u0a75', '\u0a75'), ('\u0a81', '\u0a82'),
+ ('\u0abc', '\u0abc'), ('\u0ac1', '\u0ac5'), ('\u0ac7', '\u0ac8'), ('\u0acd', '\u0acd'),
+ ('\u0ae2', '\u0ae3'), ('\u0b01', '\u0b01'), ('\u0b3c', '\u0b3c'), ('\u0b3f', '\u0b3f'),
+ ('\u0b41', '\u0b44'), ('\u0b4d', '\u0b4d'), ('\u0b56', '\u0b56'), ('\u0b62', '\u0b63'),
+ ('\u0b82', '\u0b82'), ('\u0bc0', '\u0bc0'), ('\u0bcd', '\u0bcd'), ('\u0c00', '\u0c00'),
+ ('\u0c3e', '\u0c40'), ('\u0c46', '\u0c48'), ('\u0c4a', '\u0c4d'), ('\u0c55', '\u0c56'),
+ ('\u0c62', '\u0c63'), ('\u0c81', '\u0c81'), ('\u0cbc', '\u0cbc'), ('\u0cbf', '\u0cbf'),
+ ('\u0cc6', '\u0cc6'), ('\u0ccc', '\u0ccd'), ('\u0ce2', '\u0ce3'), ('\u0d01', '\u0d01'),
+ ('\u0d41', '\u0d44'), ('\u0d4d', '\u0d4d'), ('\u0d62', '\u0d63'), ('\u0dca', '\u0dca'),
+ ('\u0dd2', '\u0dd4'), ('\u0dd6', '\u0dd6'), ('\u0e31', '\u0e31'), ('\u0e34', '\u0e3a'),
+ ('\u0e47', '\u0e4e'), ('\u0eb1', '\u0eb1'), ('\u0eb4', '\u0eb9'), ('\u0ebb', '\u0ebc'),
+ ('\u0ec8', '\u0ecd'), ('\u0f18', '\u0f19'), ('\u0f35', '\u0f35'), ('\u0f37', '\u0f37'),
+ ('\u0f39', '\u0f39'), ('\u0f71', '\u0f7e'), ('\u0f80', '\u0f84'), ('\u0f86', '\u0f87'),
+ ('\u0f8d', '\u0f97'), ('\u0f99', '\u0fbc'), ('\u0fc6', '\u0fc6'), ('\u102d', '\u1030'),
+ ('\u1032', '\u1037'), ('\u1039', '\u103a'), ('\u103d', '\u103e'), ('\u1058', '\u1059'),
+ ('\u105e', '\u1060'), ('\u1071', '\u1074'), ('\u1082', '\u1082'), ('\u1085', '\u1086'),
+ ('\u108d', '\u108d'), ('\u109d', '\u109d'), ('\u135d', '\u135f'), ('\u1712', '\u1714'),
+ ('\u1732', '\u1734'), ('\u1752', '\u1753'), ('\u1772', '\u1773'), ('\u17b4', '\u17b5'),
+ ('\u17b7', '\u17bd'), ('\u17c6', '\u17c6'), ('\u17c9', '\u17d3'), ('\u17dd', '\u17dd'),
+ ('\u180b', '\u180d'), ('\u18a9', '\u18a9'), ('\u1920', '\u1922'), ('\u1927', '\u1928'),
+ ('\u1932', '\u1932'), ('\u1939', '\u193b'), ('\u1a17', '\u1a18'), ('\u1a1b', '\u1a1b'),
+ ('\u1a56', '\u1a56'), ('\u1a58', '\u1a5e'), ('\u1a60', '\u1a60'), ('\u1a62', '\u1a62'),
+ ('\u1a65', '\u1a6c'), ('\u1a73', '\u1a7c'), ('\u1a7f', '\u1a7f'), ('\u1ab0', '\u1abd'),
+ ('\u1b00', '\u1b03'), ('\u1b34', '\u1b34'), ('\u1b36', '\u1b3a'), ('\u1b3c', '\u1b3c'),
+ ('\u1b42', '\u1b42'), ('\u1b6b', '\u1b73'), ('\u1b80', '\u1b81'), ('\u1ba2', '\u1ba5'),
+ ('\u1ba8', '\u1ba9'), ('\u1bab', '\u1bad'), ('\u1be6', '\u1be6'), ('\u1be8', '\u1be9'),
+ ('\u1bed', '\u1bed'), ('\u1bef', '\u1bf1'), ('\u1c2c', '\u1c33'), ('\u1c36', '\u1c37'),
+ ('\u1cd0', '\u1cd2'), ('\u1cd4', '\u1ce0'), ('\u1ce2', '\u1ce8'), ('\u1ced', '\u1ced'),
+ ('\u1cf4', '\u1cf4'), ('\u1cf8', '\u1cf9'), ('\u1dc0', '\u1df5'), ('\u1dfc', '\u1dff'),
+ ('\u20d0', '\u20dc'), ('\u20e1', '\u20e1'), ('\u20e5', '\u20f0'), ('\u2cef', '\u2cf1'),
+ ('\u2d7f', '\u2d7f'), ('\u2de0', '\u2dff'), ('\u302a', '\u302d'), ('\u3099', '\u309a'),
+ ('\ua66f', '\ua66f'), ('\ua674', '\ua67d'), ('\ua69f', '\ua69f'), ('\ua6f0', '\ua6f1'),
+ ('\ua802', '\ua802'), ('\ua806', '\ua806'), ('\ua80b', '\ua80b'), ('\ua825', '\ua826'),
+ ('\ua8c4', '\ua8c4'), ('\ua8e0', '\ua8f1'), ('\ua926', '\ua92d'), ('\ua947', '\ua951'),
+ ('\ua980', '\ua982'), ('\ua9b3', '\ua9b3'), ('\ua9b6', '\ua9b9'), ('\ua9bc', '\ua9bc'),
+ ('\ua9e5', '\ua9e5'), ('\uaa29', '\uaa2e'), ('\uaa31', '\uaa32'), ('\uaa35', '\uaa36'),
+ ('\uaa43', '\uaa43'), ('\uaa4c', '\uaa4c'), ('\uaa7c', '\uaa7c'), ('\uaab0', '\uaab0'),
+ ('\uaab2', '\uaab4'), ('\uaab7', '\uaab8'), ('\uaabe', '\uaabf'), ('\uaac1', '\uaac1'),
+ ('\uaaec', '\uaaed'), ('\uaaf6', '\uaaf6'), ('\uabe5', '\uabe5'), ('\uabe8', '\uabe8'),
+ ('\uabed', '\uabed'), ('\ufb1e', '\ufb1e'), ('\ufe00', '\ufe0f'), ('\ufe20', '\ufe2d'),
+ ('\U000101fd', '\U000101fd'), ('\U000102e0', '\U000102e0'), ('\U00010376', '\U0001037a'),
+ ('\U00010a01', '\U00010a03'), ('\U00010a05', '\U00010a06'), ('\U00010a0c', '\U00010a0f'),
+ ('\U00010a38', '\U00010a3a'), ('\U00010a3f', '\U00010a3f'), ('\U00010ae5', '\U00010ae6'),
+ ('\U00011001', '\U00011001'), ('\U00011038', '\U00011046'), ('\U0001107f', '\U00011081'),
+ ('\U000110b3', '\U000110b6'), ('\U000110b9', '\U000110ba'), ('\U00011100', '\U00011102'),
+ ('\U00011127', '\U0001112b'), ('\U0001112d', '\U00011134'), ('\U00011173', '\U00011173'),
+ ('\U00011180', '\U00011181'), ('\U000111b6', '\U000111be'), ('\U0001122f', '\U00011231'),
+ ('\U00011234', '\U00011234'), ('\U00011236', '\U00011237'), ('\U000112df', '\U000112df'),
+ ('\U000112e3', '\U000112ea'), ('\U00011301', '\U00011301'), ('\U0001133c', '\U0001133c'),
+ ('\U00011340', '\U00011340'), ('\U00011366', '\U0001136c'), ('\U00011370', '\U00011374'),
+ ('\U000114b3', '\U000114b8'), ('\U000114ba', '\U000114ba'), ('\U000114bf', '\U000114c0'),
+ ('\U000114c2', '\U000114c3'), ('\U000115b2', '\U000115b5'), ('\U000115bc', '\U000115bd'),
+ ('\U000115bf', '\U000115c0'), ('\U00011633', '\U0001163a'), ('\U0001163d', '\U0001163d'),
+ ('\U0001163f', '\U00011640'), ('\U000116ab', '\U000116ab'), ('\U000116ad', '\U000116ad'),
+ ('\U000116b0', '\U000116b5'), ('\U000116b7', '\U000116b7'), ('\U00016af0', '\U00016af4'),
+ ('\U00016b30', '\U00016b36'), ('\U00016f8f', '\U00016f92'), ('\U0001bc9d', '\U0001bc9e'),
+ ('\U0001d167', '\U0001d169'), ('\U0001d17b', '\U0001d182'), ('\U0001d185', '\U0001d18b'),
+ ('\U0001d1aa', '\U0001d1ad'), ('\U0001d242', '\U0001d244'), ('\U0001e8d0', '\U0001e8d6'),
+ ('\U000e0100', '\U000e01ef')
+ ];
+
+ pub static N_table: &'static [(char, char)] = &[
+ ('\x30', '\x39'), ('\u0660', '\u0669'), ('\u06f0', '\u06f9'), ('\u07c0', '\u07c9'),
+ ('\u0966', '\u096f'), ('\u09e6', '\u09ef'), ('\u0a66', '\u0a6f'), ('\u0ae6', '\u0aef'),
+ ('\u0b66', '\u0b6f'), ('\u0be6', '\u0bef'), ('\u0c66', '\u0c6f'), ('\u0ce6', '\u0cef'),
+ ('\u0d66', '\u0d6f'), ('\u0de6', '\u0def'), ('\u0e50', '\u0e59'), ('\u0ed0', '\u0ed9'),
+ ('\u0f20', '\u0f29'), ('\u1040', '\u1049'), ('\u1090', '\u1099'), ('\u16ee', '\u16f0'),
+ ('\u17e0', '\u17e9'), ('\u1810', '\u1819'), ('\u1946', '\u194f'), ('\u19d0', '\u19d9'),
+ ('\u1a80', '\u1a89'), ('\u1a90', '\u1a99'), ('\u1b50', '\u1b59'), ('\u1bb0', '\u1bb9'),
+ ('\u1c40', '\u1c49'), ('\u1c50', '\u1c59'), ('\u2160', '\u2182'), ('\u2185', '\u2188'),
+ ('\u3007', '\u3007'), ('\u3021', '\u3029'), ('\u3038', '\u303a'), ('\ua620', '\ua629'),
+ ('\ua6e6', '\ua6ef'), ('\ua8d0', '\ua8d9'), ('\ua900', '\ua909'), ('\ua9d0', '\ua9d9'),
+ ('\ua9f0', '\ua9f9'), ('\uaa50', '\uaa59'), ('\uabf0', '\uabf9'), ('\uff10', '\uff19'),
+ ('\U00010140', '\U00010174'), ('\U00010341', '\U00010341'), ('\U0001034a', '\U0001034a'),
+ ('\U000103d1', '\U000103d5'), ('\U000104a0', '\U000104a9'), ('\U00011066', '\U0001106f'),
+ ('\U000110f0', '\U000110f9'), ('\U00011136', '\U0001113f'), ('\U000111d0', '\U000111d9'),
+ ('\U000112f0', '\U000112f9'), ('\U000114d0', '\U000114d9'), ('\U00011650', '\U00011659'),
+ ('\U000116c0', '\U000116c9'), ('\U000118e0', '\U000118e9'), ('\U00012400', '\U0001246e'),
+ ('\U00016a60', '\U00016a69'), ('\U00016b50', '\U00016b59'), ('\U0001d7ce', '\U0001d7ff')
+ ];
+
+ pub fn N(c: char) -> bool {
+ super::bsearch_range_table(c, N_table)
+ }
+
+ pub static Nd_table: &'static [(char, char)] = &[
+ ('\x30', '\x39'), ('\u0660', '\u0669'), ('\u06f0', '\u06f9'), ('\u07c0', '\u07c9'),
+ ('\u0966', '\u096f'), ('\u09e6', '\u09ef'), ('\u0a66', '\u0a6f'), ('\u0ae6', '\u0aef'),
+ ('\u0b66', '\u0b6f'), ('\u0be6', '\u0bef'), ('\u0c66', '\u0c6f'), ('\u0ce6', '\u0cef'),
+ ('\u0d66', '\u0d6f'), ('\u0de6', '\u0def'), ('\u0e50', '\u0e59'), ('\u0ed0', '\u0ed9'),
+ ('\u0f20', '\u0f29'), ('\u1040', '\u1049'), ('\u1090', '\u1099'), ('\u17e0', '\u17e9'),
+ ('\u1810', '\u1819'), ('\u1946', '\u194f'), ('\u19d0', '\u19d9'), ('\u1a80', '\u1a89'),
+ ('\u1a90', '\u1a99'), ('\u1b50', '\u1b59'), ('\u1bb0', '\u1bb9'), ('\u1c40', '\u1c49'),
+ ('\u1c50', '\u1c59'), ('\ua620', '\ua629'), ('\ua8d0', '\ua8d9'), ('\ua900', '\ua909'),
+ ('\ua9d0', '\ua9d9'), ('\ua9f0', '\ua9f9'), ('\uaa50', '\uaa59'), ('\uabf0', '\uabf9'),
+ ('\uff10', '\uff19'), ('\U000104a0', '\U000104a9'), ('\U00011066', '\U0001106f'),
+ ('\U000110f0', '\U000110f9'), ('\U00011136', '\U0001113f'), ('\U000111d0', '\U000111d9'),
+ ('\U000112f0', '\U000112f9'), ('\U000114d0', '\U000114d9'), ('\U00011650', '\U00011659'),
+ ('\U000116c0', '\U000116c9'), ('\U000118e0', '\U000118e9'), ('\U00016a60', '\U00016a69'),
+ ('\U00016b50', '\U00016b59'), ('\U0001d7ce', '\U0001d7ff')
+ ];
+
+ pub static Nl_table: &'static [(char, char)] = &[
+ ('\u16ee', '\u16f0'), ('\u2160', '\u2182'), ('\u2185', '\u2188'), ('\u3007', '\u3007'),
+ ('\u3021', '\u3029'), ('\u3038', '\u303a'), ('\ua6e6', '\ua6ef'), ('\U00010140',
+ '\U00010174'), ('\U00010341', '\U00010341'), ('\U0001034a', '\U0001034a'), ('\U000103d1',
+ '\U000103d5'), ('\U00012400', '\U0001246e')
+ ];
+
+ pub static No_table: &'static [(char, char)] = &[
+ ('\xb2', '\xb3'), ('\xb9', '\xb9'), ('\xbc', '\xbe'), ('\u09f4', '\u09f9'), ('\u0b72',
+ '\u0b77'), ('\u0bf0', '\u0bf2'), ('\u0c78', '\u0c7e'), ('\u0d70', '\u0d75'), ('\u0f2a',
+ '\u0f33'), ('\u1369', '\u137c'), ('\u17f0', '\u17f9'), ('\u19da', '\u19da'), ('\u2070',
+ '\u2070'), ('\u2074', '\u2079'), ('\u2080', '\u2089'), ('\u2150', '\u215f'), ('\u2189',
+ '\u2189'), ('\u2460', '\u249b'), ('\u24ea', '\u24ff'), ('\u2776', '\u2793'), ('\u2cfd',
+ '\u2cfd'), ('\u3192', '\u3195'), ('\u3220', '\u3229'), ('\u3248', '\u324f'), ('\u3251',
+ '\u325f'), ('\u3280', '\u3289'), ('\u32b1', '\u32bf'), ('\ua830', '\ua835'), ('\U00010107',
+ '\U00010133'), ('\U00010175', '\U00010178'), ('\U0001018a', '\U0001018b'), ('\U000102e1',
+ '\U000102fb'), ('\U00010320', '\U00010323'), ('\U00010858', '\U0001085f'), ('\U00010879',
+ '\U0001087f'), ('\U000108a7', '\U000108af'), ('\U00010916', '\U0001091b'), ('\U00010a40',
+ '\U00010a47'), ('\U00010a7d', '\U00010a7e'), ('\U00010a9d', '\U00010a9f'), ('\U00010aeb',
+ '\U00010aef'), ('\U00010b58', '\U00010b5f'), ('\U00010b78', '\U00010b7f'), ('\U00010ba9',
+ '\U00010baf'), ('\U00010e60', '\U00010e7e'), ('\U00011052', '\U00011065'), ('\U000111e1',
+ '\U000111f4'), ('\U000118ea', '\U000118f2'), ('\U00016b5b', '\U00016b61'), ('\U0001d360',
+ '\U0001d371'), ('\U0001e8c7', '\U0001e8cf'), ('\U0001f100', '\U0001f10c')
+ ];
+
+ pub static P_table: &'static [(char, char)] = &[
+ ('\x21', '\x23'), ('\x25', '\x2a'), ('\x2c', '\x2f'), ('\x3a', '\x3b'), ('\x3f', '\x40'),
+ ('\x5b', '\x5d'), ('\x5f', '\x5f'), ('\x7b', '\x7b'), ('\x7d', '\x7d'), ('\xa1', '\xa1'),
+ ('\xa7', '\xa7'), ('\xab', '\xab'), ('\xb6', '\xb7'), ('\xbb', '\xbb'), ('\xbf', '\xbf'),
+ ('\u037e', '\u037e'), ('\u0387', '\u0387'), ('\u055a', '\u055f'), ('\u0589', '\u058a'),
+ ('\u05be', '\u05be'), ('\u05c0', '\u05c0'), ('\u05c3', '\u05c3'), ('\u05c6', '\u05c6'),
+ ('\u05f3', '\u05f4'), ('\u0609', '\u060a'), ('\u060c', '\u060d'), ('\u061b', '\u061b'),
+ ('\u061e', '\u061f'), ('\u066a', '\u066d'), ('\u06d4', '\u06d4'), ('\u0700', '\u070d'),
+ ('\u07f7', '\u07f9'), ('\u0830', '\u083e'), ('\u085e', '\u085e'), ('\u0964', '\u0965'),
+ ('\u0970', '\u0970'), ('\u0af0', '\u0af0'), ('\u0df4', '\u0df4'), ('\u0e4f', '\u0e4f'),
+ ('\u0e5a', '\u0e5b'), ('\u0f04', '\u0f12'), ('\u0f14', '\u0f14'), ('\u0f3a', '\u0f3d'),
+ ('\u0f85', '\u0f85'), ('\u0fd0', '\u0fd4'), ('\u0fd9', '\u0fda'), ('\u104a', '\u104f'),
+ ('\u10fb', '\u10fb'), ('\u1360', '\u1368'), ('\u1400', '\u1400'), ('\u166d', '\u166e'),
+ ('\u169b', '\u169c'), ('\u16eb', '\u16ed'), ('\u1735', '\u1736'), ('\u17d4', '\u17d6'),
+ ('\u17d8', '\u17da'), ('\u1800', '\u180a'), ('\u1944', '\u1945'), ('\u1a1e', '\u1a1f'),
+ ('\u1aa0', '\u1aa6'), ('\u1aa8', '\u1aad'), ('\u1b5a', '\u1b60'), ('\u1bfc', '\u1bff'),
+ ('\u1c3b', '\u1c3f'), ('\u1c7e', '\u1c7f'), ('\u1cc0', '\u1cc7'), ('\u1cd3', '\u1cd3'),
+ ('\u2010', '\u2027'), ('\u2030', '\u2043'), ('\u2045', '\u2051'), ('\u2053', '\u205e'),
+ ('\u207d', '\u207e'), ('\u208d', '\u208e'), ('\u2308', '\u230b'), ('\u2329', '\u232a'),
+ ('\u2768', '\u2775'), ('\u27c5', '\u27c6'), ('\u27e6', '\u27ef'), ('\u2983', '\u2998'),
+ ('\u29d8', '\u29db'), ('\u29fc', '\u29fd'), ('\u2cf9', '\u2cfc'), ('\u2cfe', '\u2cff'),
+ ('\u2d70', '\u2d70'), ('\u2e00', '\u2e2e'), ('\u2e30', '\u2e42'), ('\u3001', '\u3003'),
+ ('\u3008', '\u3011'), ('\u3014', '\u301f'), ('\u3030', '\u3030'), ('\u303d', '\u303d'),
+ ('\u30a0', '\u30a0'), ('\u30fb', '\u30fb'), ('\ua4fe', '\ua4ff'), ('\ua60d', '\ua60f'),
+ ('\ua673', '\ua673'), ('\ua67e', '\ua67e'), ('\ua6f2', '\ua6f7'), ('\ua874', '\ua877'),
+ ('\ua8ce', '\ua8cf'), ('\ua8f8', '\ua8fa'), ('\ua92e', '\ua92f'), ('\ua95f', '\ua95f'),
+ ('\ua9c1', '\ua9cd'), ('\ua9de', '\ua9df'), ('\uaa5c', '\uaa5f'), ('\uaade', '\uaadf'),
+ ('\uaaf0', '\uaaf1'), ('\uabeb', '\uabeb'), ('\ufd3e', '\ufd3f'), ('\ufe10', '\ufe19'),
+ ('\ufe30', '\ufe52'), ('\ufe54', '\ufe61'), ('\ufe63', '\ufe63'), ('\ufe68', '\ufe68'),
+ ('\ufe6a', '\ufe6b'), ('\uff01', '\uff03'), ('\uff05', '\uff0a'), ('\uff0c', '\uff0f'),
+ ('\uff1a', '\uff1b'), ('\uff1f', '\uff20'), ('\uff3b', '\uff3d'), ('\uff3f', '\uff3f'),
+ ('\uff5b', '\uff5b'), ('\uff5d', '\uff5d'), ('\uff5f', '\uff65'), ('\U00010100',
+ '\U00010102'), ('\U0001039f', '\U0001039f'), ('\U000103d0', '\U000103d0'), ('\U0001056f',
+ '\U0001056f'), ('\U00010857', '\U00010857'), ('\U0001091f', '\U0001091f'), ('\U0001093f',
+ '\U0001093f'), ('\U00010a50', '\U00010a58'), ('\U00010a7f', '\U00010a7f'), ('\U00010af0',
+ '\U00010af6'), ('\U00010b39', '\U00010b3f'), ('\U00010b99', '\U00010b9c'), ('\U00011047',
+ '\U0001104d'), ('\U000110bb', '\U000110bc'), ('\U000110be', '\U000110c1'), ('\U00011140',
+ '\U00011143'), ('\U00011174', '\U00011175'), ('\U000111c5', '\U000111c8'), ('\U000111cd',
+ '\U000111cd'), ('\U00011238', '\U0001123d'), ('\U000114c6', '\U000114c6'), ('\U000115c1',
+ '\U000115c9'), ('\U00011641', '\U00011643'), ('\U00012470', '\U00012474'), ('\U00016a6e',
+ '\U00016a6f'), ('\U00016af5', '\U00016af5'), ('\U00016b37', '\U00016b3b'), ('\U00016b44',
+ '\U00016b44'), ('\U0001bc9f', '\U0001bc9f')
+ ];
+
+ pub static Pc_table: &'static [(char, char)] = &[
+ ('\x5f', '\x5f'), ('\u203f', '\u2040'), ('\u2054', '\u2054'), ('\ufe33', '\ufe34'),
+ ('\ufe4d', '\ufe4f'), ('\uff3f', '\uff3f')
+ ];
+
+ pub static Pd_table: &'static [(char, char)] = &[
+ ('\x2d', '\x2d'), ('\u058a', '\u058a'), ('\u05be', '\u05be'), ('\u1400', '\u1400'),
+ ('\u1806', '\u1806'), ('\u2010', '\u2015'), ('\u2e17', '\u2e17'), ('\u2e1a', '\u2e1a'),
+ ('\u2e3a', '\u2e3b'), ('\u2e40', '\u2e40'), ('\u301c', '\u301c'), ('\u3030', '\u3030'),
+ ('\u30a0', '\u30a0'), ('\ufe31', '\ufe32'), ('\ufe58', '\ufe58'), ('\ufe63', '\ufe63'),
+ ('\uff0d', '\uff0d')
+ ];
+
+ pub static Pe_table: &'static [(char, char)] = &[
+ ('\x29', '\x29'), ('\x5d', '\x5d'), ('\x7d', '\x7d'), ('\u0f3b', '\u0f3b'), ('\u0f3d',
+ '\u0f3d'), ('\u169c', '\u169c'), ('\u2046', '\u2046'), ('\u207e', '\u207e'), ('\u208e',
+ '\u208e'), ('\u2309', '\u2309'), ('\u230b', '\u230b'), ('\u232a', '\u232a'), ('\u2769',
+ '\u2769'), ('\u276b', '\u276b'), ('\u276d', '\u276d'), ('\u276f', '\u276f'), ('\u2771',
+ '\u2771'), ('\u2773', '\u2773'), ('\u2775', '\u2775'), ('\u27c6', '\u27c6'), ('\u27e7',
+ '\u27e7'), ('\u27e9', '\u27e9'), ('\u27eb', '\u27eb'), ('\u27ed', '\u27ed'), ('\u27ef',
+ '\u27ef'), ('\u2984', '\u2984'), ('\u2986', '\u2986'), ('\u2988', '\u2988'), ('\u298a',
+ '\u298a'), ('\u298c', '\u298c'), ('\u298e', '\u298e'), ('\u2990', '\u2990'), ('\u2992',
+ '\u2992'), ('\u2994', '\u2994'), ('\u2996', '\u2996'), ('\u2998', '\u2998'), ('\u29d9',
+ '\u29d9'), ('\u29db', '\u29db'), ('\u29fd', '\u29fd'), ('\u2e23', '\u2e23'), ('\u2e25',
+ '\u2e25'), ('\u2e27', '\u2e27'), ('\u2e29', '\u2e29'), ('\u3009', '\u3009'), ('\u300b',
+ '\u300b'), ('\u300d', '\u300d'), ('\u300f', '\u300f'), ('\u3011', '\u3011'), ('\u3015',
+ '\u3015'), ('\u3017', '\u3017'), ('\u3019', '\u3019'), ('\u301b', '\u301b'), ('\u301e',
+ '\u301f'), ('\ufd3e', '\ufd3e'), ('\ufe18', '\ufe18'), ('\ufe36', '\ufe36'), ('\ufe38',
+ '\ufe38'), ('\ufe3a', '\ufe3a'), ('\ufe3c', '\ufe3c'), ('\ufe3e', '\ufe3e'), ('\ufe40',
+ '\ufe40'), ('\ufe42', '\ufe42'), ('\ufe44', '\ufe44'), ('\ufe48', '\ufe48'), ('\ufe5a',
+ '\ufe5a'), ('\ufe5c', '\ufe5c'), ('\ufe5e', '\ufe5e'), ('\uff09', '\uff09'), ('\uff3d',
+ '\uff3d'), ('\uff5d', '\uff5d'), ('\uff60', '\uff60'), ('\uff63', '\uff63')
+ ];
+
+ pub static Pf_table: &'static [(char, char)] = &[
+ ('\xbb', '\xbb'), ('\u2019', '\u2019'), ('\u201d', '\u201d'), ('\u203a', '\u203a'),
+ ('\u2e03', '\u2e03'), ('\u2e05', '\u2e05'), ('\u2e0a', '\u2e0a'), ('\u2e0d', '\u2e0d'),
+ ('\u2e1d', '\u2e1d'), ('\u2e21', '\u2e21')
+ ];
+
+ pub static Pi_table: &'static [(char, char)] = &[
+ ('\xab', '\xab'), ('\u2018', '\u2018'), ('\u201b', '\u201c'), ('\u201f', '\u201f'),
+ ('\u2039', '\u2039'), ('\u2e02', '\u2e02'), ('\u2e04', '\u2e04'), ('\u2e09', '\u2e09'),
+ ('\u2e0c', '\u2e0c'), ('\u2e1c', '\u2e1c'), ('\u2e20', '\u2e20')
+ ];
+
+ pub static Po_table: &'static [(char, char)] = &[
+ ('\x21', '\x23'), ('\x25', '\x27'), ('\x2a', '\x2a'), ('\x2c', '\x2c'), ('\x2e', '\x2f'),
+ ('\x3a', '\x3b'), ('\x3f', '\x40'), ('\x5c', '\x5c'), ('\xa1', '\xa1'), ('\xa7', '\xa7'),
+ ('\xb6', '\xb7'), ('\xbf', '\xbf'), ('\u037e', '\u037e'), ('\u0387', '\u0387'), ('\u055a',
+ '\u055f'), ('\u0589', '\u0589'), ('\u05c0', '\u05c0'), ('\u05c3', '\u05c3'), ('\u05c6',
+ '\u05c6'), ('\u05f3', '\u05f4'), ('\u0609', '\u060a'), ('\u060c', '\u060d'), ('\u061b',
+ '\u061b'), ('\u061e', '\u061f'), ('\u066a', '\u066d'), ('\u06d4', '\u06d4'), ('\u0700',
+ '\u070d'), ('\u07f7', '\u07f9'), ('\u0830', '\u083e'), ('\u085e', '\u085e'), ('\u0964',
+ '\u0965'), ('\u0970', '\u0970'), ('\u0af0', '\u0af0'), ('\u0df4', '\u0df4'), ('\u0e4f',
+ '\u0e4f'), ('\u0e5a', '\u0e5b'), ('\u0f04', '\u0f12'), ('\u0f14', '\u0f14'), ('\u0f85',
+ '\u0f85'), ('\u0fd0', '\u0fd4'), ('\u0fd9', '\u0fda'), ('\u104a', '\u104f'), ('\u10fb',
+ '\u10fb'), ('\u1360', '\u1368'), ('\u166d', '\u166e'), ('\u16eb', '\u16ed'), ('\u1735',
+ '\u1736'), ('\u17d4', '\u17d6'), ('\u17d8', '\u17da'), ('\u1800', '\u1805'), ('\u1807',
+ '\u180a'), ('\u1944', '\u1945'), ('\u1a1e', '\u1a1f'), ('\u1aa0', '\u1aa6'), ('\u1aa8',
+ '\u1aad'), ('\u1b5a', '\u1b60'), ('\u1bfc', '\u1bff'), ('\u1c3b', '\u1c3f'), ('\u1c7e',
+ '\u1c7f'), ('\u1cc0', '\u1cc7'), ('\u1cd3', '\u1cd3'), ('\u2016', '\u2017'), ('\u2020',
+ '\u2027'), ('\u2030', '\u2038'), ('\u203b', '\u203e'), ('\u2041', '\u2043'), ('\u2047',
+ '\u2051'), ('\u2053', '\u2053'), ('\u2055', '\u205e'), ('\u2cf9', '\u2cfc'), ('\u2cfe',
+ '\u2cff'), ('\u2d70', '\u2d70'), ('\u2e00', '\u2e01'), ('\u2e06', '\u2e08'), ('\u2e0b',
+ '\u2e0b'), ('\u2e0e', '\u2e16'), ('\u2e18', '\u2e19'), ('\u2e1b', '\u2e1b'), ('\u2e1e',
+ '\u2e1f'), ('\u2e2a', '\u2e2e'), ('\u2e30', '\u2e39'), ('\u2e3c', '\u2e3f'), ('\u2e41',
+ '\u2e41'), ('\u3001', '\u3003'), ('\u303d', '\u303d'), ('\u30fb', '\u30fb'), ('\ua4fe',
+ '\ua4ff'), ('\ua60d', '\ua60f'), ('\ua673', '\ua673'), ('\ua67e', '\ua67e'), ('\ua6f2',
+ '\ua6f7'), ('\ua874', '\ua877'), ('\ua8ce', '\ua8cf'), ('\ua8f8', '\ua8fa'), ('\ua92e',
+ '\ua92f'), ('\ua95f', '\ua95f'), ('\ua9c1', '\ua9cd'), ('\ua9de', '\ua9df'), ('\uaa5c',
+ '\uaa5f'), ('\uaade', '\uaadf'), ('\uaaf0', '\uaaf1'), ('\uabeb', '\uabeb'), ('\ufe10',
+ '\ufe16'), ('\ufe19', '\ufe19'), ('\ufe30', '\ufe30'), ('\ufe45', '\ufe46'), ('\ufe49',
+ '\ufe4c'), ('\ufe50', '\ufe52'), ('\ufe54', '\ufe57'), ('\ufe5f', '\ufe61'), ('\ufe68',
+ '\ufe68'), ('\ufe6a', '\ufe6b'), ('\uff01', '\uff03'), ('\uff05', '\uff07'), ('\uff0a',
+ '\uff0a'), ('\uff0c', '\uff0c'), ('\uff0e', '\uff0f'), ('\uff1a', '\uff1b'), ('\uff1f',
+ '\uff20'), ('\uff3c', '\uff3c'), ('\uff61', '\uff61'), ('\uff64', '\uff65'), ('\U00010100',
+ '\U00010102'), ('\U0001039f', '\U0001039f'), ('\U000103d0', '\U000103d0'), ('\U0001056f',
+ '\U0001056f'), ('\U00010857', '\U00010857'), ('\U0001091f', '\U0001091f'), ('\U0001093f',
+ '\U0001093f'), ('\U00010a50', '\U00010a58'), ('\U00010a7f', '\U00010a7f'), ('\U00010af0',
+ '\U00010af6'), ('\U00010b39', '\U00010b3f'), ('\U00010b99', '\U00010b9c'), ('\U00011047',
+ '\U0001104d'), ('\U000110bb', '\U000110bc'), ('\U000110be', '\U000110c1'), ('\U00011140',
+ '\U00011143'), ('\U00011174', '\U00011175'), ('\U000111c5', '\U000111c8'), ('\U000111cd',
+ '\U000111cd'), ('\U00011238', '\U0001123d'), ('\U000114c6', '\U000114c6'), ('\U000115c1',
+ '\U000115c9'), ('\U00011641', '\U00011643'), ('\U00012470', '\U00012474'), ('\U00016a6e',
+ '\U00016a6f'), ('\U00016af5', '\U00016af5'), ('\U00016b37', '\U00016b3b'), ('\U00016b44',
+ '\U00016b44'), ('\U0001bc9f', '\U0001bc9f')
+ ];
+
+ pub static Ps_table: &'static [(char, char)] = &[
+ ('\x28', '\x28'), ('\x5b', '\x5b'), ('\x7b', '\x7b'), ('\u0f3a', '\u0f3a'), ('\u0f3c',
+ '\u0f3c'), ('\u169b', '\u169b'), ('\u201a', '\u201a'), ('\u201e', '\u201e'), ('\u2045',
+ '\u2045'), ('\u207d', '\u207d'), ('\u208d', '\u208d'), ('\u2308', '\u2308'), ('\u230a',
+ '\u230a'), ('\u2329', '\u2329'), ('\u2768', '\u2768'), ('\u276a', '\u276a'), ('\u276c',
+ '\u276c'), ('\u276e', '\u276e'), ('\u2770', '\u2770'), ('\u2772', '\u2772'), ('\u2774',
+ '\u2774'), ('\u27c5', '\u27c5'), ('\u27e6', '\u27e6'), ('\u27e8', '\u27e8'), ('\u27ea',
+ '\u27ea'), ('\u27ec', '\u27ec'), ('\u27ee', '\u27ee'), ('\u2983', '\u2983'), ('\u2985',
+ '\u2985'), ('\u2987', '\u2987'), ('\u2989', '\u2989'), ('\u298b', '\u298b'), ('\u298d',
+ '\u298d'), ('\u298f', '\u298f'), ('\u2991', '\u2991'), ('\u2993', '\u2993'), ('\u2995',
+ '\u2995'), ('\u2997', '\u2997'), ('\u29d8', '\u29d8'), ('\u29da', '\u29da'), ('\u29fc',
+ '\u29fc'), ('\u2e22', '\u2e22'), ('\u2e24', '\u2e24'), ('\u2e26', '\u2e26'), ('\u2e28',
+ '\u2e28'), ('\u2e42', '\u2e42'), ('\u3008', '\u3008'), ('\u300a', '\u300a'), ('\u300c',
+ '\u300c'), ('\u300e', '\u300e'), ('\u3010', '\u3010'), ('\u3014', '\u3014'), ('\u3016',
+ '\u3016'), ('\u3018', '\u3018'), ('\u301a', '\u301a'), ('\u301d', '\u301d'), ('\ufd3f',
+ '\ufd3f'), ('\ufe17', '\ufe17'), ('\ufe35', '\ufe35'), ('\ufe37', '\ufe37'), ('\ufe39',
+ '\ufe39'), ('\ufe3b', '\ufe3b'), ('\ufe3d', '\ufe3d'), ('\ufe3f', '\ufe3f'), ('\ufe41',
+ '\ufe41'), ('\ufe43', '\ufe43'), ('\ufe47', '\ufe47'), ('\ufe59', '\ufe59'), ('\ufe5b',
+ '\ufe5b'), ('\ufe5d', '\ufe5d'), ('\uff08', '\uff08'), ('\uff3b', '\uff3b'), ('\uff5b',
+ '\uff5b'), ('\uff5f', '\uff5f'), ('\uff62', '\uff62')
+ ];
+
+ pub static S_table: &'static [(char, char)] = &[
+ ('\x24', '\x24'), ('\x2b', '\x2b'), ('\x3c', '\x3e'), ('\x5e', '\x5e'), ('\x60', '\x60'),
+ ('\x7c', '\x7c'), ('\x7e', '\x7e'), ('\xa2', '\xa6'), ('\xa8', '\xa9'), ('\xac', '\xac'),
+ ('\xae', '\xb1'), ('\xb4', '\xb4'), ('\xb8', '\xb8'), ('\xd7', '\xd7'), ('\xf7', '\xf7'),
+ ('\u02c2', '\u02c5'), ('\u02d2', '\u02df'), ('\u02e5', '\u02eb'), ('\u02ed', '\u02ed'),
+ ('\u02ef', '\u02ff'), ('\u0375', '\u0375'), ('\u0384', '\u0385'), ('\u03f6', '\u03f6'),
+ ('\u0482', '\u0482'), ('\u058d', '\u058f'), ('\u0606', '\u0608'), ('\u060b', '\u060b'),
+ ('\u060e', '\u060f'), ('\u06de', '\u06de'), ('\u06e9', '\u06e9'), ('\u06fd', '\u06fe'),
+ ('\u07f6', '\u07f6'), ('\u09f2', '\u09f3'), ('\u09fa', '\u09fb'), ('\u0af1', '\u0af1'),
+ ('\u0b70', '\u0b70'), ('\u0bf3', '\u0bfa'), ('\u0c7f', '\u0c7f'), ('\u0d79', '\u0d79'),
+ ('\u0e3f', '\u0e3f'), ('\u0f01', '\u0f03'), ('\u0f13', '\u0f13'), ('\u0f15', '\u0f17'),
+ ('\u0f1a', '\u0f1f'), ('\u0f34', '\u0f34'), ('\u0f36', '\u0f36'), ('\u0f38', '\u0f38'),
+ ('\u0fbe', '\u0fc5'), ('\u0fc7', '\u0fcc'), ('\u0fce', '\u0fcf'), ('\u0fd5', '\u0fd8'),
+ ('\u109e', '\u109f'), ('\u1390', '\u1399'), ('\u17db', '\u17db'), ('\u1940', '\u1940'),
+ ('\u19de', '\u19ff'), ('\u1b61', '\u1b6a'), ('\u1b74', '\u1b7c'), ('\u1fbd', '\u1fbd'),
+ ('\u1fbf', '\u1fc1'), ('\u1fcd', '\u1fcf'), ('\u1fdd', '\u1fdf'), ('\u1fed', '\u1fef'),
+ ('\u1ffd', '\u1ffe'), ('\u2044', '\u2044'), ('\u2052', '\u2052'), ('\u207a', '\u207c'),
+ ('\u208a', '\u208c'), ('\u20a0', '\u20bd'), ('\u2100', '\u2101'), ('\u2103', '\u2106'),
+ ('\u2108', '\u2109'), ('\u2114', '\u2114'), ('\u2116', '\u2118'), ('\u211e', '\u2123'),
+ ('\u2125', '\u2125'), ('\u2127', '\u2127'), ('\u2129', '\u2129'), ('\u212e', '\u212e'),
+ ('\u213a', '\u213b'), ('\u2140', '\u2144'), ('\u214a', '\u214d'), ('\u214f', '\u214f'),
+ ('\u2190', '\u2307'), ('\u230c', '\u2328'), ('\u232b', '\u23fa'), ('\u2400', '\u2426'),
+ ('\u2440', '\u244a'), ('\u249c', '\u24e9'), ('\u2500', '\u2767'), ('\u2794', '\u27c4'),
+ ('\u27c7', '\u27e5'), ('\u27f0', '\u2982'), ('\u2999', '\u29d7'), ('\u29dc', '\u29fb'),
+ ('\u29fe', '\u2b73'), ('\u2b76', '\u2b95'), ('\u2b98', '\u2bb9'), ('\u2bbd', '\u2bc8'),
+ ('\u2bca', '\u2bd1'), ('\u2ce5', '\u2cea'), ('\u2e80', '\u2e99'), ('\u2e9b', '\u2ef3'),
+ ('\u2f00', '\u2fd5'), ('\u2ff0', '\u2ffb'), ('\u3004', '\u3004'), ('\u3012', '\u3013'),
+ ('\u3020', '\u3020'), ('\u3036', '\u3037'), ('\u303e', '\u303f'), ('\u309b', '\u309c'),
+ ('\u3190', '\u3191'), ('\u3196', '\u319f'), ('\u31c0', '\u31e3'), ('\u3200', '\u321e'),
+ ('\u322a', '\u3247'), ('\u3250', '\u3250'), ('\u3260', '\u327f'), ('\u328a', '\u32b0'),
+ ('\u32c0', '\u32fe'), ('\u3300', '\u33ff'), ('\u4dc0', '\u4dff'), ('\ua490', '\ua4c6'),
+ ('\ua700', '\ua716'), ('\ua720', '\ua721'), ('\ua789', '\ua78a'), ('\ua828', '\ua82b'),
+ ('\ua836', '\ua839'), ('\uaa77', '\uaa79'), ('\uab5b', '\uab5b'), ('\ufb29', '\ufb29'),
+ ('\ufbb2', '\ufbc1'), ('\ufdfc', '\ufdfd'), ('\ufe62', '\ufe62'), ('\ufe64', '\ufe66'),
+ ('\ufe69', '\ufe69'), ('\uff04', '\uff04'), ('\uff0b', '\uff0b'), ('\uff1c', '\uff1e'),
+ ('\uff3e', '\uff3e'), ('\uff40', '\uff40'), ('\uff5c', '\uff5c'), ('\uff5e', '\uff5e'),
+ ('\uffe0', '\uffe6'), ('\uffe8', '\uffee'), ('\ufffc', '\ufffd'), ('\U00010137',
+ '\U0001013f'), ('\U00010179', '\U00010189'), ('\U0001018c', '\U0001018c'), ('\U00010190',
+ '\U0001019b'), ('\U000101a0', '\U000101a0'), ('\U000101d0', '\U000101fc'), ('\U00010877',
+ '\U00010878'), ('\U00010ac8', '\U00010ac8'), ('\U00016b3c', '\U00016b3f'), ('\U00016b45',
+ '\U00016b45'), ('\U0001bc9c', '\U0001bc9c'), ('\U0001d000', '\U0001d0f5'), ('\U0001d100',
+ '\U0001d126'), ('\U0001d129', '\U0001d164'), ('\U0001d16a', '\U0001d16c'), ('\U0001d183',
+ '\U0001d184'), ('\U0001d18c', '\U0001d1a9'), ('\U0001d1ae', '\U0001d1dd'), ('\U0001d200',
+ '\U0001d241'), ('\U0001d245', '\U0001d245'), ('\U0001d300', '\U0001d356'), ('\U0001d6c1',
+ '\U0001d6c1'), ('\U0001d6db', '\U0001d6db'), ('\U0001d6fb', '\U0001d6fb'), ('\U0001d715',
+ '\U0001d715'), ('\U0001d735', '\U0001d735'), ('\U0001d74f', '\U0001d74f'), ('\U0001d76f',
+ '\U0001d76f'), ('\U0001d789', '\U0001d789'), ('\U0001d7a9', '\U0001d7a9'), ('\U0001d7c3',
+ '\U0001d7c3'), ('\U0001eef0', '\U0001eef1'), ('\U0001f000', '\U0001f02b'), ('\U0001f030',
+ '\U0001f093'), ('\U0001f0a0', '\U0001f0ae'), ('\U0001f0b1', '\U0001f0bf'), ('\U0001f0c1',
+ '\U0001f0cf'), ('\U0001f0d1', '\U0001f0f5'), ('\U0001f110', '\U0001f12e'), ('\U0001f130',
+ '\U0001f16b'), ('\U0001f170', '\U0001f19a'), ('\U0001f1e6', '\U0001f202'), ('\U0001f210',
+ '\U0001f23a'), ('\U0001f240', '\U0001f248'), ('\U0001f250', '\U0001f251'), ('\U0001f300',
+ '\U0001f32c'), ('\U0001f330', '\U0001f37d'), ('\U0001f380', '\U0001f3ce'), ('\U0001f3d4',
+ '\U0001f3f7'), ('\U0001f400', '\U0001f4fe'), ('\U0001f500', '\U0001f54a'), ('\U0001f550',
+ '\U0001f579'), ('\U0001f57b', '\U0001f5a3'), ('\U0001f5a5', '\U0001f642'), ('\U0001f645',
+ '\U0001f6cf'), ('\U0001f6e0', '\U0001f6ec'), ('\U0001f6f0', '\U0001f6f3'), ('\U0001f700',
+ '\U0001f773'), ('\U0001f780', '\U0001f7d4'), ('\U0001f800', '\U0001f80b'), ('\U0001f810',
+ '\U0001f847'), ('\U0001f850', '\U0001f859'), ('\U0001f860', '\U0001f887'), ('\U0001f890',
+ '\U0001f8ad')
+ ];
+
+ pub static Sc_table: &'static [(char, char)] = &[
+ ('\x24', '\x24'), ('\xa2', '\xa5'), ('\u058f', '\u058f'), ('\u060b', '\u060b'), ('\u09f2',
+ '\u09f3'), ('\u09fb', '\u09fb'), ('\u0af1', '\u0af1'), ('\u0bf9', '\u0bf9'), ('\u0e3f',
+ '\u0e3f'), ('\u17db', '\u17db'), ('\u20a0', '\u20bd'), ('\ua838', '\ua838'), ('\ufdfc',
+ '\ufdfc'), ('\ufe69', '\ufe69'), ('\uff04', '\uff04'), ('\uffe0', '\uffe1'), ('\uffe5',
+ '\uffe6')
+ ];
+
+ pub static Sk_table: &'static [(char, char)] = &[
+ ('\x5e', '\x5e'), ('\x60', '\x60'), ('\xa8', '\xa8'), ('\xaf', '\xaf'), ('\xb4', '\xb4'),
+ ('\xb8', '\xb8'), ('\u02c2', '\u02c5'), ('\u02d2', '\u02df'), ('\u02e5', '\u02eb'),
+ ('\u02ed', '\u02ed'), ('\u02ef', '\u02ff'), ('\u0375', '\u0375'), ('\u0384', '\u0385'),
+ ('\u1fbd', '\u1fbd'), ('\u1fbf', '\u1fc1'), ('\u1fcd', '\u1fcf'), ('\u1fdd', '\u1fdf'),
+ ('\u1fed', '\u1fef'), ('\u1ffd', '\u1ffe'), ('\u309b', '\u309c'), ('\ua700', '\ua716'),
+ ('\ua720', '\ua721'), ('\ua789', '\ua78a'), ('\uab5b', '\uab5b'), ('\ufbb2', '\ufbc1'),
+ ('\uff3e', '\uff3e'), ('\uff40', '\uff40'), ('\uffe3', '\uffe3')
+ ];
+
+ pub static Sm_table: &'static [(char, char)] = &[
+ ('\x2b', '\x2b'), ('\x3c', '\x3e'), ('\x7c', '\x7c'), ('\x7e', '\x7e'), ('\xac', '\xac'),
+ ('\xb1', '\xb1'), ('\xd7', '\xd7'), ('\xf7', '\xf7'), ('\u03f6', '\u03f6'), ('\u0606',
+ '\u0608'), ('\u2044', '\u2044'), ('\u2052', '\u2052'), ('\u207a', '\u207c'), ('\u208a',
+ '\u208c'), ('\u2118', '\u2118'), ('\u2140', '\u2144'), ('\u214b', '\u214b'), ('\u2190',
+ '\u2194'), ('\u219a', '\u219b'), ('\u21a0', '\u21a0'), ('\u21a3', '\u21a3'), ('\u21a6',
+ '\u21a6'), ('\u21ae', '\u21ae'), ('\u21ce', '\u21cf'), ('\u21d2', '\u21d2'), ('\u21d4',
+ '\u21d4'), ('\u21f4', '\u22ff'), ('\u2320', '\u2321'), ('\u237c', '\u237c'), ('\u239b',
+ '\u23b3'), ('\u23dc', '\u23e1'), ('\u25b7', '\u25b7'), ('\u25c1', '\u25c1'), ('\u25f8',
+ '\u25ff'), ('\u266f', '\u266f'), ('\u27c0', '\u27c4'), ('\u27c7', '\u27e5'), ('\u27f0',
+ '\u27ff'), ('\u2900', '\u2982'), ('\u2999', '\u29d7'), ('\u29dc', '\u29fb'), ('\u29fe',
+ '\u2aff'), ('\u2b30', '\u2b44'), ('\u2b47', '\u2b4c'), ('\ufb29', '\ufb29'), ('\ufe62',
+ '\ufe62'), ('\ufe64', '\ufe66'), ('\uff0b', '\uff0b'), ('\uff1c', '\uff1e'), ('\uff5c',
+ '\uff5c'), ('\uff5e', '\uff5e'), ('\uffe2', '\uffe2'), ('\uffe9', '\uffec'), ('\U0001d6c1',
+ '\U0001d6c1'), ('\U0001d6db', '\U0001d6db'), ('\U0001d6fb', '\U0001d6fb'), ('\U0001d715',
+ '\U0001d715'), ('\U0001d735', '\U0001d735'), ('\U0001d74f', '\U0001d74f'), ('\U0001d76f',
+ '\U0001d76f'), ('\U0001d789', '\U0001d789'), ('\U0001d7a9', '\U0001d7a9'), ('\U0001d7c3',
+ '\U0001d7c3'), ('\U0001eef0', '\U0001eef1')
+ ];
+
+ pub static So_table: &'static [(char, char)] = &[
+ ('\xa6', '\xa6'), ('\xa9', '\xa9'), ('\xae', '\xae'), ('\xb0', '\xb0'), ('\u0482',
+ '\u0482'), ('\u058d', '\u058e'), ('\u060e', '\u060f'), ('\u06de', '\u06de'), ('\u06e9',
+ '\u06e9'), ('\u06fd', '\u06fe'), ('\u07f6', '\u07f6'), ('\u09fa', '\u09fa'), ('\u0b70',
+ '\u0b70'), ('\u0bf3', '\u0bf8'), ('\u0bfa', '\u0bfa'), ('\u0c7f', '\u0c7f'), ('\u0d79',
+ '\u0d79'), ('\u0f01', '\u0f03'), ('\u0f13', '\u0f13'), ('\u0f15', '\u0f17'), ('\u0f1a',
+ '\u0f1f'), ('\u0f34', '\u0f34'), ('\u0f36', '\u0f36'), ('\u0f38', '\u0f38'), ('\u0fbe',
+ '\u0fc5'), ('\u0fc7', '\u0fcc'), ('\u0fce', '\u0fcf'), ('\u0fd5', '\u0fd8'), ('\u109e',
+ '\u109f'), ('\u1390', '\u1399'), ('\u1940', '\u1940'), ('\u19de', '\u19ff'), ('\u1b61',
+ '\u1b6a'), ('\u1b74', '\u1b7c'), ('\u2100', '\u2101'), ('\u2103', '\u2106'), ('\u2108',
+ '\u2109'), ('\u2114', '\u2114'), ('\u2116', '\u2117'), ('\u211e', '\u2123'), ('\u2125',
+ '\u2125'), ('\u2127', '\u2127'), ('\u2129', '\u2129'), ('\u212e', '\u212e'), ('\u213a',
+ '\u213b'), ('\u214a', '\u214a'), ('\u214c', '\u214d'), ('\u214f', '\u214f'), ('\u2195',
+ '\u2199'), ('\u219c', '\u219f'), ('\u21a1', '\u21a2'), ('\u21a4', '\u21a5'), ('\u21a7',
+ '\u21ad'), ('\u21af', '\u21cd'), ('\u21d0', '\u21d1'), ('\u21d3', '\u21d3'), ('\u21d5',
+ '\u21f3'), ('\u2300', '\u2307'), ('\u230c', '\u231f'), ('\u2322', '\u2328'), ('\u232b',
+ '\u237b'), ('\u237d', '\u239a'), ('\u23b4', '\u23db'), ('\u23e2', '\u23fa'), ('\u2400',
+ '\u2426'), ('\u2440', '\u244a'), ('\u249c', '\u24e9'), ('\u2500', '\u25b6'), ('\u25b8',
+ '\u25c0'), ('\u25c2', '\u25f7'), ('\u2600', '\u266e'), ('\u2670', '\u2767'), ('\u2794',
+ '\u27bf'), ('\u2800', '\u28ff'), ('\u2b00', '\u2b2f'), ('\u2b45', '\u2b46'), ('\u2b4d',
+ '\u2b73'), ('\u2b76', '\u2b95'), ('\u2b98', '\u2bb9'), ('\u2bbd', '\u2bc8'), ('\u2bca',
+ '\u2bd1'), ('\u2ce5', '\u2cea'), ('\u2e80', '\u2e99'), ('\u2e9b', '\u2ef3'), ('\u2f00',
+ '\u2fd5'), ('\u2ff0', '\u2ffb'), ('\u3004', '\u3004'), ('\u3012', '\u3013'), ('\u3020',
+ '\u3020'), ('\u3036', '\u3037'), ('\u303e', '\u303f'), ('\u3190', '\u3191'), ('\u3196',
+ '\u319f'), ('\u31c0', '\u31e3'), ('\u3200', '\u321e'), ('\u322a', '\u3247'), ('\u3250',
+ '\u3250'), ('\u3260', '\u327f'), ('\u328a', '\u32b0'), ('\u32c0', '\u32fe'), ('\u3300',
+ '\u33ff'), ('\u4dc0', '\u4dff'), ('\ua490', '\ua4c6'), ('\ua828', '\ua82b'), ('\ua836',
+ '\ua837'), ('\ua839', '\ua839'), ('\uaa77', '\uaa79'), ('\ufdfd', '\ufdfd'), ('\uffe4',
+ '\uffe4'), ('\uffe8', '\uffe8'), ('\uffed', '\uffee'), ('\ufffc', '\ufffd'), ('\U00010137',
+ '\U0001013f'), ('\U00010179', '\U00010189'), ('\U0001018c', '\U0001018c'), ('\U00010190',
+ '\U0001019b'), ('\U000101a0', '\U000101a0'), ('\U000101d0', '\U000101fc'), ('\U00010877',
+ '\U00010878'), ('\U00010ac8', '\U00010ac8'), ('\U00016b3c', '\U00016b3f'), ('\U00016b45',
+ '\U00016b45'), ('\U0001bc9c', '\U0001bc9c'), ('\U0001d000', '\U0001d0f5'), ('\U0001d100',
+ '\U0001d126'), ('\U0001d129', '\U0001d164'), ('\U0001d16a', '\U0001d16c'), ('\U0001d183',
+ '\U0001d184'), ('\U0001d18c', '\U0001d1a9'), ('\U0001d1ae', '\U0001d1dd'), ('\U0001d200',
+ '\U0001d241'), ('\U0001d245', '\U0001d245'), ('\U0001d300', '\U0001d356'), ('\U0001f000',
+ '\U0001f02b'), ('\U0001f030', '\U0001f093'), ('\U0001f0a0', '\U0001f0ae'), ('\U0001f0b1',
+ '\U0001f0bf'), ('\U0001f0c1', '\U0001f0cf'), ('\U0001f0d1', '\U0001f0f5'), ('\U0001f110',
+ '\U0001f12e'), ('\U0001f130', '\U0001f16b'), ('\U0001f170', '\U0001f19a'), ('\U0001f1e6',
+ '\U0001f202'), ('\U0001f210', '\U0001f23a'), ('\U0001f240', '\U0001f248'), ('\U0001f250',
+ '\U0001f251'), ('\U0001f300', '\U0001f32c'), ('\U0001f330', '\U0001f37d'), ('\U0001f380',
+ '\U0001f3ce'), ('\U0001f3d4', '\U0001f3f7'), ('\U0001f400', '\U0001f4fe'), ('\U0001f500',
+ '\U0001f54a'), ('\U0001f550', '\U0001f579'), ('\U0001f57b', '\U0001f5a3'), ('\U0001f5a5',
+ '\U0001f642'), ('\U0001f645', '\U0001f6cf'), ('\U0001f6e0', '\U0001f6ec'), ('\U0001f6f0',
+ '\U0001f6f3'), ('\U0001f700', '\U0001f773'), ('\U0001f780', '\U0001f7d4'), ('\U0001f800',
+ '\U0001f80b'), ('\U0001f810', '\U0001f847'), ('\U0001f850', '\U0001f859'), ('\U0001f860',
+ '\U0001f887'), ('\U0001f890', '\U0001f8ad')
+ ];
+
+ pub static Z_table: &'static [(char, char)] = &[
+ ('\x20', '\x20'), ('\xa0', '\xa0'), ('\u1680', '\u1680'), ('\u2000', '\u200a'), ('\u2028',
+ '\u2029'), ('\u202f', '\u202f'), ('\u205f', '\u205f'), ('\u3000', '\u3000')
+ ];
+
+ pub static Zl_table: &'static [(char, char)] = &[
+ ('\u2028', '\u2028')
+ ];
+
+ pub static Zp_table: &'static [(char, char)] = &[
+ ('\u2029', '\u2029')
+ ];
+
+ pub static Zs_table: &'static [(char, char)] = &[
+ ('\x20', '\x20'), ('\xa0', '\xa0'), ('\u1680', '\u1680'), ('\u2000', '\u200a'), ('\u202f',
+ '\u202f'), ('\u205f', '\u205f'), ('\u3000', '\u3000')
+ ];
+
+}
+
+pub mod derived_property {
+ pub static Alphabetic_table: &'static [(char, char)] = &[
+ ('\x41', '\x5a'), ('\x61', '\x7a'), ('\xaa', '\xaa'), ('\xb5', '\xb5'), ('\xba', '\xba'),
+ ('\xc0', '\xd6'), ('\xd8', '\xf6'), ('\xf8', '\u01ba'), ('\u01bb', '\u01bb'), ('\u01bc',
+ '\u01bf'), ('\u01c0', '\u01c3'), ('\u01c4', '\u0293'), ('\u0294', '\u0294'), ('\u0295',
+ '\u02af'), ('\u02b0', '\u02c1'), ('\u02c6', '\u02d1'), ('\u02e0', '\u02e4'), ('\u02ec',
+ '\u02ec'), ('\u02ee', '\u02ee'), ('\u0345', '\u0345'), ('\u0370', '\u0373'), ('\u0374',
+ '\u0374'), ('\u0376', '\u0377'), ('\u037a', '\u037a'), ('\u037b', '\u037d'), ('\u037f',
+ '\u037f'), ('\u0386', '\u0386'), ('\u0388', '\u038a'), ('\u038c', '\u038c'), ('\u038e',
+ '\u03a1'), ('\u03a3', '\u03f5'), ('\u03f7', '\u0481'), ('\u048a', '\u052f'), ('\u0531',
+ '\u0556'), ('\u0559', '\u0559'), ('\u0561', '\u0587'), ('\u05b0', '\u05bd'), ('\u05bf',
+ '\u05bf'), ('\u05c1', '\u05c2'), ('\u05c4', '\u05c5'), ('\u05c7', '\u05c7'), ('\u05d0',
+ '\u05ea'), ('\u05f0', '\u05f2'), ('\u0610', '\u061a'), ('\u0620', '\u063f'), ('\u0640',
+ '\u0640'), ('\u0641', '\u064a'), ('\u064b', '\u0657'), ('\u0659', '\u065f'), ('\u066e',
+ '\u066f'), ('\u0670', '\u0670'), ('\u0671', '\u06d3'), ('\u06d5', '\u06d5'), ('\u06d6',
+ '\u06dc'), ('\u06e1', '\u06e4'), ('\u06e5', '\u06e6'), ('\u06e7', '\u06e8'), ('\u06ed',
+ '\u06ed'), ('\u06ee', '\u06ef'), ('\u06fa', '\u06fc'), ('\u06ff', '\u06ff'), ('\u0710',
+ '\u0710'), ('\u0711', '\u0711'), ('\u0712', '\u072f'), ('\u0730', '\u073f'), ('\u074d',
+ '\u07a5'), ('\u07a6', '\u07b0'), ('\u07b1', '\u07b1'), ('\u07ca', '\u07ea'), ('\u07f4',
+ '\u07f5'), ('\u07fa', '\u07fa'), ('\u0800', '\u0815'), ('\u0816', '\u0817'), ('\u081a',
+ '\u081a'), ('\u081b', '\u0823'), ('\u0824', '\u0824'), ('\u0825', '\u0827'), ('\u0828',
+ '\u0828'), ('\u0829', '\u082c'), ('\u0840', '\u0858'), ('\u08a0', '\u08b2'), ('\u08e4',
+ '\u08e9'), ('\u08f0', '\u0902'), ('\u0903', '\u0903'), ('\u0904', '\u0939'), ('\u093a',
+ '\u093a'), ('\u093b', '\u093b'), ('\u093d', '\u093d'), ('\u093e', '\u0940'), ('\u0941',
+ '\u0948'), ('\u0949', '\u094c'), ('\u094e', '\u094f'), ('\u0950', '\u0950'), ('\u0955',
+ '\u0957'), ('\u0958', '\u0961'), ('\u0962', '\u0963'), ('\u0971', '\u0971'), ('\u0972',
+ '\u0980'), ('\u0981', '\u0981'), ('\u0982', '\u0983'), ('\u0985', '\u098c'), ('\u098f',
+ '\u0990'), ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'), ('\u09b2', '\u09b2'), ('\u09b6',
+ '\u09b9'), ('\u09bd', '\u09bd'), ('\u09be', '\u09c0'), ('\u09c1', '\u09c4'), ('\u09c7',
+ '\u09c8'), ('\u09cb', '\u09cc'), ('\u09ce', '\u09ce'), ('\u09d7', '\u09d7'), ('\u09dc',
+ '\u09dd'), ('\u09df', '\u09e1'), ('\u09e2', '\u09e3'), ('\u09f0', '\u09f1'), ('\u0a01',
+ '\u0a02'), ('\u0a03', '\u0a03'), ('\u0a05', '\u0a0a'), ('\u0a0f', '\u0a10'), ('\u0a13',
+ '\u0a28'), ('\u0a2a', '\u0a30'), ('\u0a32', '\u0a33'), ('\u0a35', '\u0a36'), ('\u0a38',
+ '\u0a39'), ('\u0a3e', '\u0a40'), ('\u0a41', '\u0a42'), ('\u0a47', '\u0a48'), ('\u0a4b',
+ '\u0a4c'), ('\u0a51', '\u0a51'), ('\u0a59', '\u0a5c'), ('\u0a5e', '\u0a5e'), ('\u0a70',
+ '\u0a71'), ('\u0a72', '\u0a74'), ('\u0a75', '\u0a75'), ('\u0a81', '\u0a82'), ('\u0a83',
+ '\u0a83'), ('\u0a85', '\u0a8d'), ('\u0a8f', '\u0a91'), ('\u0a93', '\u0aa8'), ('\u0aaa',
+ '\u0ab0'), ('\u0ab2', '\u0ab3'), ('\u0ab5', '\u0ab9'), ('\u0abd', '\u0abd'), ('\u0abe',
+ '\u0ac0'), ('\u0ac1', '\u0ac5'), ('\u0ac7', '\u0ac8'), ('\u0ac9', '\u0ac9'), ('\u0acb',
+ '\u0acc'), ('\u0ad0', '\u0ad0'), ('\u0ae0', '\u0ae1'), ('\u0ae2', '\u0ae3'), ('\u0b01',
+ '\u0b01'), ('\u0b02', '\u0b03'), ('\u0b05', '\u0b0c'), ('\u0b0f', '\u0b10'), ('\u0b13',
+ '\u0b28'), ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'), ('\u0b35', '\u0b39'), ('\u0b3d',
+ '\u0b3d'), ('\u0b3e', '\u0b3e'), ('\u0b3f', '\u0b3f'), ('\u0b40', '\u0b40'), ('\u0b41',
+ '\u0b44'), ('\u0b47', '\u0b48'), ('\u0b4b', '\u0b4c'), ('\u0b56', '\u0b56'), ('\u0b57',
+ '\u0b57'), ('\u0b5c', '\u0b5d'), ('\u0b5f', '\u0b61'), ('\u0b62', '\u0b63'), ('\u0b71',
+ '\u0b71'), ('\u0b82', '\u0b82'), ('\u0b83', '\u0b83'), ('\u0b85', '\u0b8a'), ('\u0b8e',
+ '\u0b90'), ('\u0b92', '\u0b95'), ('\u0b99', '\u0b9a'), ('\u0b9c', '\u0b9c'), ('\u0b9e',
+ '\u0b9f'), ('\u0ba3', '\u0ba4'), ('\u0ba8', '\u0baa'), ('\u0bae', '\u0bb9'), ('\u0bbe',
+ '\u0bbf'), ('\u0bc0', '\u0bc0'), ('\u0bc1', '\u0bc2'), ('\u0bc6', '\u0bc8'), ('\u0bca',
+ '\u0bcc'), ('\u0bd0', '\u0bd0'), ('\u0bd7', '\u0bd7'), ('\u0c00', '\u0c00'), ('\u0c01',
+ '\u0c03'), ('\u0c05', '\u0c0c'), ('\u0c0e', '\u0c10'), ('\u0c12', '\u0c28'), ('\u0c2a',
+ '\u0c39'), ('\u0c3d', '\u0c3d'), ('\u0c3e', '\u0c40'), ('\u0c41', '\u0c44'), ('\u0c46',
+ '\u0c48'), ('\u0c4a', '\u0c4c'), ('\u0c55', '\u0c56'), ('\u0c58', '\u0c59'), ('\u0c60',
+ '\u0c61'), ('\u0c62', '\u0c63'), ('\u0c81', '\u0c81'), ('\u0c82', '\u0c83'), ('\u0c85',
+ '\u0c8c'), ('\u0c8e', '\u0c90'), ('\u0c92', '\u0ca8'), ('\u0caa', '\u0cb3'), ('\u0cb5',
+ '\u0cb9'), ('\u0cbd', '\u0cbd'), ('\u0cbe', '\u0cbe'), ('\u0cbf', '\u0cbf'), ('\u0cc0',
+ '\u0cc4'), ('\u0cc6', '\u0cc6'), ('\u0cc7', '\u0cc8'), ('\u0cca', '\u0ccb'), ('\u0ccc',
+ '\u0ccc'), ('\u0cd5', '\u0cd6'), ('\u0cde', '\u0cde'), ('\u0ce0', '\u0ce1'), ('\u0ce2',
+ '\u0ce3'), ('\u0cf1', '\u0cf2'), ('\u0d01', '\u0d01'), ('\u0d02', '\u0d03'), ('\u0d05',
+ '\u0d0c'), ('\u0d0e', '\u0d10'), ('\u0d12', '\u0d3a'), ('\u0d3d', '\u0d3d'), ('\u0d3e',
+ '\u0d40'), ('\u0d41', '\u0d44'), ('\u0d46', '\u0d48'), ('\u0d4a', '\u0d4c'), ('\u0d4e',
+ '\u0d4e'), ('\u0d57', '\u0d57'), ('\u0d60', '\u0d61'), ('\u0d62', '\u0d63'), ('\u0d7a',
+ '\u0d7f'), ('\u0d82', '\u0d83'), ('\u0d85', '\u0d96'), ('\u0d9a', '\u0db1'), ('\u0db3',
+ '\u0dbb'), ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'), ('\u0dcf', '\u0dd1'), ('\u0dd2',
+ '\u0dd4'), ('\u0dd6', '\u0dd6'), ('\u0dd8', '\u0ddf'), ('\u0df2', '\u0df3'), ('\u0e01',
+ '\u0e30'), ('\u0e31', '\u0e31'), ('\u0e32', '\u0e33'), ('\u0e34', '\u0e3a'), ('\u0e40',
+ '\u0e45'), ('\u0e46', '\u0e46'), ('\u0e4d', '\u0e4d'), ('\u0e81', '\u0e82'), ('\u0e84',
+ '\u0e84'), ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'), ('\u0e8d', '\u0e8d'), ('\u0e94',
+ '\u0e97'), ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'), ('\u0ea5', '\u0ea5'), ('\u0ea7',
+ '\u0ea7'), ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'), ('\u0eb1', '\u0eb1'), ('\u0eb2',
+ '\u0eb3'), ('\u0eb4', '\u0eb9'), ('\u0ebb', '\u0ebc'), ('\u0ebd', '\u0ebd'), ('\u0ec0',
+ '\u0ec4'), ('\u0ec6', '\u0ec6'), ('\u0ecd', '\u0ecd'), ('\u0edc', '\u0edf'), ('\u0f00',
+ '\u0f00'), ('\u0f40', '\u0f47'), ('\u0f49', '\u0f6c'), ('\u0f71', '\u0f7e'), ('\u0f7f',
+ '\u0f7f'), ('\u0f80', '\u0f81'), ('\u0f88', '\u0f8c'), ('\u0f8d', '\u0f97'), ('\u0f99',
+ '\u0fbc'), ('\u1000', '\u102a'), ('\u102b', '\u102c'), ('\u102d', '\u1030'), ('\u1031',
+ '\u1031'), ('\u1032', '\u1036'), ('\u1038', '\u1038'), ('\u103b', '\u103c'), ('\u103d',
+ '\u103e'), ('\u103f', '\u103f'), ('\u1050', '\u1055'), ('\u1056', '\u1057'), ('\u1058',
+ '\u1059'), ('\u105a', '\u105d'), ('\u105e', '\u1060'), ('\u1061', '\u1061'), ('\u1062',
+ '\u1062'), ('\u1065', '\u1066'), ('\u1067', '\u1068'), ('\u106e', '\u1070'), ('\u1071',
+ '\u1074'), ('\u1075', '\u1081'), ('\u1082', '\u1082'), ('\u1083', '\u1084'), ('\u1085',
+ '\u1086'), ('\u108e', '\u108e'), ('\u109c', '\u109c'), ('\u109d', '\u109d'), ('\u10a0',
+ '\u10c5'), ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'), ('\u10d0', '\u10fa'), ('\u10fc',
+ '\u10fc'), ('\u10fd', '\u1248'), ('\u124a', '\u124d'), ('\u1250', '\u1256'), ('\u1258',
+ '\u1258'), ('\u125a', '\u125d'), ('\u1260', '\u1288'), ('\u128a', '\u128d'), ('\u1290',
+ '\u12b0'), ('\u12b2', '\u12b5'), ('\u12b8', '\u12be'), ('\u12c0', '\u12c0'), ('\u12c2',
+ '\u12c5'), ('\u12c8', '\u12d6'), ('\u12d8', '\u1310'), ('\u1312', '\u1315'), ('\u1318',
+ '\u135a'), ('\u135f', '\u135f'), ('\u1380', '\u138f'), ('\u13a0', '\u13f4'), ('\u1401',
+ '\u166c'), ('\u166f', '\u167f'), ('\u1681', '\u169a'), ('\u16a0', '\u16ea'), ('\u16ee',
+ '\u16f0'), ('\u16f1', '\u16f8'), ('\u1700', '\u170c'), ('\u170e', '\u1711'), ('\u1712',
+ '\u1713'), ('\u1720', '\u1731'), ('\u1732', '\u1733'), ('\u1740', '\u1751'), ('\u1752',
+ '\u1753'), ('\u1760', '\u176c'), ('\u176e', '\u1770'), ('\u1772', '\u1773'), ('\u1780',
+ '\u17b3'), ('\u17b6', '\u17b6'), ('\u17b7', '\u17bd'), ('\u17be', '\u17c5'), ('\u17c6',
+ '\u17c6'), ('\u17c7', '\u17c8'), ('\u17d7', '\u17d7'), ('\u17dc', '\u17dc'), ('\u1820',
+ '\u1842'), ('\u1843', '\u1843'), ('\u1844', '\u1877'), ('\u1880', '\u18a8'), ('\u18a9',
+ '\u18a9'), ('\u18aa', '\u18aa'), ('\u18b0', '\u18f5'), ('\u1900', '\u191e'), ('\u1920',
+ '\u1922'), ('\u1923', '\u1926'), ('\u1927', '\u1928'), ('\u1929', '\u192b'), ('\u1930',
+ '\u1931'), ('\u1932', '\u1932'), ('\u1933', '\u1938'), ('\u1950', '\u196d'), ('\u1970',
+ '\u1974'), ('\u1980', '\u19ab'), ('\u19b0', '\u19c0'), ('\u19c1', '\u19c7'), ('\u19c8',
+ '\u19c9'), ('\u1a00', '\u1a16'), ('\u1a17', '\u1a18'), ('\u1a19', '\u1a1a'), ('\u1a1b',
+ '\u1a1b'), ('\u1a20', '\u1a54'), ('\u1a55', '\u1a55'), ('\u1a56', '\u1a56'), ('\u1a57',
+ '\u1a57'), ('\u1a58', '\u1a5e'), ('\u1a61', '\u1a61'), ('\u1a62', '\u1a62'), ('\u1a63',
+ '\u1a64'), ('\u1a65', '\u1a6c'), ('\u1a6d', '\u1a72'), ('\u1a73', '\u1a74'), ('\u1aa7',
+ '\u1aa7'), ('\u1b00', '\u1b03'), ('\u1b04', '\u1b04'), ('\u1b05', '\u1b33'), ('\u1b35',
+ '\u1b35'), ('\u1b36', '\u1b3a'), ('\u1b3b', '\u1b3b'), ('\u1b3c', '\u1b3c'), ('\u1b3d',
+ '\u1b41'), ('\u1b42', '\u1b42'), ('\u1b43', '\u1b43'), ('\u1b45', '\u1b4b'), ('\u1b80',
+ '\u1b81'), ('\u1b82', '\u1b82'), ('\u1b83', '\u1ba0'), ('\u1ba1', '\u1ba1'), ('\u1ba2',
+ '\u1ba5'), ('\u1ba6', '\u1ba7'), ('\u1ba8', '\u1ba9'), ('\u1bac', '\u1bad'), ('\u1bae',
+ '\u1baf'), ('\u1bba', '\u1be5'), ('\u1be7', '\u1be7'), ('\u1be8', '\u1be9'), ('\u1bea',
+ '\u1bec'), ('\u1bed', '\u1bed'), ('\u1bee', '\u1bee'), ('\u1bef', '\u1bf1'), ('\u1c00',
+ '\u1c23'), ('\u1c24', '\u1c2b'), ('\u1c2c', '\u1c33'), ('\u1c34', '\u1c35'), ('\u1c4d',
+ '\u1c4f'), ('\u1c5a', '\u1c77'), ('\u1c78', '\u1c7d'), ('\u1ce9', '\u1cec'), ('\u1cee',
+ '\u1cf1'), ('\u1cf2', '\u1cf3'), ('\u1cf5', '\u1cf6'), ('\u1d00', '\u1d2b'), ('\u1d2c',
+ '\u1d6a'), ('\u1d6b', '\u1d77'), ('\u1d78', '\u1d78'), ('\u1d79', '\u1d9a'), ('\u1d9b',
+ '\u1dbf'), ('\u1de7', '\u1df4'), ('\u1e00', '\u1f15'), ('\u1f18', '\u1f1d'), ('\u1f20',
+ '\u1f45'), ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'), ('\u1f59', '\u1f59'), ('\u1f5b',
+ '\u1f5b'), ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'), ('\u1f80', '\u1fb4'), ('\u1fb6',
+ '\u1fbc'), ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fcc'), ('\u1fd0',
+ '\u1fd3'), ('\u1fd6', '\u1fdb'), ('\u1fe0', '\u1fec'), ('\u1ff2', '\u1ff4'), ('\u1ff6',
+ '\u1ffc'), ('\u2071', '\u2071'), ('\u207f', '\u207f'), ('\u2090', '\u209c'), ('\u2102',
+ '\u2102'), ('\u2107', '\u2107'), ('\u210a', '\u2113'), ('\u2115', '\u2115'), ('\u2119',
+ '\u211d'), ('\u2124', '\u2124'), ('\u2126', '\u2126'), ('\u2128', '\u2128'), ('\u212a',
+ '\u212d'), ('\u212f', '\u2134'), ('\u2135', '\u2138'), ('\u2139', '\u2139'), ('\u213c',
+ '\u213f'), ('\u2145', '\u2149'), ('\u214e', '\u214e'), ('\u2160', '\u2182'), ('\u2183',
+ '\u2184'), ('\u2185', '\u2188'), ('\u24b6', '\u24e9'), ('\u2c00', '\u2c2e'), ('\u2c30',
+ '\u2c5e'), ('\u2c60', '\u2c7b'), ('\u2c7c', '\u2c7d'), ('\u2c7e', '\u2ce4'), ('\u2ceb',
+ '\u2cee'), ('\u2cf2', '\u2cf3'), ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'), ('\u2d2d',
+ '\u2d2d'), ('\u2d30', '\u2d67'), ('\u2d6f', '\u2d6f'), ('\u2d80', '\u2d96'), ('\u2da0',
+ '\u2da6'), ('\u2da8', '\u2dae'), ('\u2db0', '\u2db6'), ('\u2db8', '\u2dbe'), ('\u2dc0',
+ '\u2dc6'), ('\u2dc8', '\u2dce'), ('\u2dd0', '\u2dd6'), ('\u2dd8', '\u2dde'), ('\u2de0',
+ '\u2dff'), ('\u2e2f', '\u2e2f'), ('\u3005', '\u3005'), ('\u3006', '\u3006'), ('\u3007',
+ '\u3007'), ('\u3021', '\u3029'), ('\u3031', '\u3035'), ('\u3038', '\u303a'), ('\u303b',
+ '\u303b'), ('\u303c', '\u303c'), ('\u3041', '\u3096'), ('\u309d', '\u309e'), ('\u309f',
+ '\u309f'), ('\u30a1', '\u30fa'), ('\u30fc', '\u30fe'), ('\u30ff', '\u30ff'), ('\u3105',
+ '\u312d'), ('\u3131', '\u318e'), ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'), ('\u3400',
+ '\u4db5'), ('\u4e00', '\u9fcc'), ('\ua000', '\ua014'), ('\ua015', '\ua015'), ('\ua016',
+ '\ua48c'), ('\ua4d0', '\ua4f7'), ('\ua4f8', '\ua4fd'), ('\ua500', '\ua60b'), ('\ua60c',
+ '\ua60c'), ('\ua610', '\ua61f'), ('\ua62a', '\ua62b'), ('\ua640', '\ua66d'), ('\ua66e',
+ '\ua66e'), ('\ua674', '\ua67b'), ('\ua67f', '\ua67f'), ('\ua680', '\ua69b'), ('\ua69c',
+ '\ua69d'), ('\ua69f', '\ua69f'), ('\ua6a0', '\ua6e5'), ('\ua6e6', '\ua6ef'), ('\ua717',
+ '\ua71f'), ('\ua722', '\ua76f'), ('\ua770', '\ua770'), ('\ua771', '\ua787'), ('\ua788',
+ '\ua788'), ('\ua78b', '\ua78e'), ('\ua790', '\ua7ad'), ('\ua7b0', '\ua7b1'), ('\ua7f7',
+ '\ua7f7'), ('\ua7f8', '\ua7f9'), ('\ua7fa', '\ua7fa'), ('\ua7fb', '\ua801'), ('\ua803',
+ '\ua805'), ('\ua807', '\ua80a'), ('\ua80c', '\ua822'), ('\ua823', '\ua824'), ('\ua825',
+ '\ua826'), ('\ua827', '\ua827'), ('\ua840', '\ua873'), ('\ua880', '\ua881'), ('\ua882',
+ '\ua8b3'), ('\ua8b4', '\ua8c3'), ('\ua8f2', '\ua8f7'), ('\ua8fb', '\ua8fb'), ('\ua90a',
+ '\ua925'), ('\ua926', '\ua92a'), ('\ua930', '\ua946'), ('\ua947', '\ua951'), ('\ua952',
+ '\ua952'), ('\ua960', '\ua97c'), ('\ua980', '\ua982'), ('\ua983', '\ua983'), ('\ua984',
+ '\ua9b2'), ('\ua9b4', '\ua9b5'), ('\ua9b6', '\ua9b9'), ('\ua9ba', '\ua9bb'), ('\ua9bc',
+ '\ua9bc'), ('\ua9bd', '\ua9bf'), ('\ua9cf', '\ua9cf'), ('\ua9e0', '\ua9e4'), ('\ua9e6',
+ '\ua9e6'), ('\ua9e7', '\ua9ef'), ('\ua9fa', '\ua9fe'), ('\uaa00', '\uaa28'), ('\uaa29',
+ '\uaa2e'), ('\uaa2f', '\uaa30'), ('\uaa31', '\uaa32'), ('\uaa33', '\uaa34'), ('\uaa35',
+ '\uaa36'), ('\uaa40', '\uaa42'), ('\uaa43', '\uaa43'), ('\uaa44', '\uaa4b'), ('\uaa4c',
+ '\uaa4c'), ('\uaa4d', '\uaa4d'), ('\uaa60', '\uaa6f'), ('\uaa70', '\uaa70'), ('\uaa71',
+ '\uaa76'), ('\uaa7a', '\uaa7a'), ('\uaa7e', '\uaaaf'), ('\uaab0', '\uaab0'), ('\uaab1',
+ '\uaab1'), ('\uaab2', '\uaab4'), ('\uaab5', '\uaab6'), ('\uaab7', '\uaab8'), ('\uaab9',
+ '\uaabd'), ('\uaabe', '\uaabe'), ('\uaac0', '\uaac0'), ('\uaac2', '\uaac2'), ('\uaadb',
+ '\uaadc'), ('\uaadd', '\uaadd'), ('\uaae0', '\uaaea'), ('\uaaeb', '\uaaeb'), ('\uaaec',
+ '\uaaed'), ('\uaaee', '\uaaef'), ('\uaaf2', '\uaaf2'), ('\uaaf3', '\uaaf4'), ('\uaaf5',
+ '\uaaf5'), ('\uab01', '\uab06'), ('\uab09', '\uab0e'), ('\uab11', '\uab16'), ('\uab20',
+ '\uab26'), ('\uab28', '\uab2e'), ('\uab30', '\uab5a'), ('\uab5c', '\uab5f'), ('\uab64',
+ '\uab65'), ('\uabc0', '\uabe2'), ('\uabe3', '\uabe4'), ('\uabe5', '\uabe5'), ('\uabe6',
+ '\uabe7'), ('\uabe8', '\uabe8'), ('\uabe9', '\uabea'), ('\uac00', '\ud7a3'), ('\ud7b0',
+ '\ud7c6'), ('\ud7cb', '\ud7fb'), ('\uf900', '\ufa6d'), ('\ufa70', '\ufad9'), ('\ufb00',
+ '\ufb06'), ('\ufb13', '\ufb17'), ('\ufb1d', '\ufb1d'), ('\ufb1e', '\ufb1e'), ('\ufb1f',
+ '\ufb28'), ('\ufb2a', '\ufb36'), ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'), ('\ufb40',
+ '\ufb41'), ('\ufb43', '\ufb44'), ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufd3d'), ('\ufd50',
+ '\ufd8f'), ('\ufd92', '\ufdc7'), ('\ufdf0', '\ufdfb'), ('\ufe70', '\ufe74'), ('\ufe76',
+ '\ufefc'), ('\uff21', '\uff3a'), ('\uff41', '\uff5a'), ('\uff66', '\uff6f'), ('\uff70',
+ '\uff70'), ('\uff71', '\uff9d'), ('\uff9e', '\uff9f'), ('\uffa0', '\uffbe'), ('\uffc2',
+ '\uffc7'), ('\uffca', '\uffcf'), ('\uffd2', '\uffd7'), ('\uffda', '\uffdc'), ('\U00010000',
+ '\U0001000b'), ('\U0001000d', '\U00010026'), ('\U00010028', '\U0001003a'), ('\U0001003c',
+ '\U0001003d'), ('\U0001003f', '\U0001004d'), ('\U00010050', '\U0001005d'), ('\U00010080',
+ '\U000100fa'), ('\U00010140', '\U00010174'), ('\U00010280', '\U0001029c'), ('\U000102a0',
+ '\U000102d0'), ('\U00010300', '\U0001031f'), ('\U00010330', '\U00010340'), ('\U00010341',
+ '\U00010341'), ('\U00010342', '\U00010349'), ('\U0001034a', '\U0001034a'), ('\U00010350',
+ '\U00010375'), ('\U00010376', '\U0001037a'), ('\U00010380', '\U0001039d'), ('\U000103a0',
+ '\U000103c3'), ('\U000103c8', '\U000103cf'), ('\U000103d1', '\U000103d5'), ('\U00010400',
+ '\U0001044f'), ('\U00010450', '\U0001049d'), ('\U00010500', '\U00010527'), ('\U00010530',
+ '\U00010563'), ('\U00010600', '\U00010736'), ('\U00010740', '\U00010755'), ('\U00010760',
+ '\U00010767'), ('\U00010800', '\U00010805'), ('\U00010808', '\U00010808'), ('\U0001080a',
+ '\U00010835'), ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'), ('\U0001083f',
+ '\U00010855'), ('\U00010860', '\U00010876'), ('\U00010880', '\U0001089e'), ('\U00010900',
+ '\U00010915'), ('\U00010920', '\U00010939'), ('\U00010980', '\U000109b7'), ('\U000109be',
+ '\U000109bf'), ('\U00010a00', '\U00010a00'), ('\U00010a01', '\U00010a03'), ('\U00010a05',
+ '\U00010a06'), ('\U00010a0c', '\U00010a0f'), ('\U00010a10', '\U00010a13'), ('\U00010a15',
+ '\U00010a17'), ('\U00010a19', '\U00010a33'), ('\U00010a60', '\U00010a7c'), ('\U00010a80',
+ '\U00010a9c'), ('\U00010ac0', '\U00010ac7'), ('\U00010ac9', '\U00010ae4'), ('\U00010b00',
+ '\U00010b35'), ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'), ('\U00010b80',
+ '\U00010b91'), ('\U00010c00', '\U00010c48'), ('\U00011000', '\U00011000'), ('\U00011001',
+ '\U00011001'), ('\U00011002', '\U00011002'), ('\U00011003', '\U00011037'), ('\U00011038',
+ '\U00011045'), ('\U00011082', '\U00011082'), ('\U00011083', '\U000110af'), ('\U000110b0',
+ '\U000110b2'), ('\U000110b3', '\U000110b6'), ('\U000110b7', '\U000110b8'), ('\U000110d0',
+ '\U000110e8'), ('\U00011100', '\U00011102'), ('\U00011103', '\U00011126'), ('\U00011127',
+ '\U0001112b'), ('\U0001112c', '\U0001112c'), ('\U0001112d', '\U00011132'), ('\U00011150',
+ '\U00011172'), ('\U00011176', '\U00011176'), ('\U00011180', '\U00011181'), ('\U00011182',
+ '\U00011182'), ('\U00011183', '\U000111b2'), ('\U000111b3', '\U000111b5'), ('\U000111b6',
+ '\U000111be'), ('\U000111bf', '\U000111bf'), ('\U000111c1', '\U000111c4'), ('\U000111da',
+ '\U000111da'), ('\U00011200', '\U00011211'), ('\U00011213', '\U0001122b'), ('\U0001122c',
+ '\U0001122e'), ('\U0001122f', '\U00011231'), ('\U00011232', '\U00011233'), ('\U00011234',
+ '\U00011234'), ('\U00011237', '\U00011237'), ('\U000112b0', '\U000112de'), ('\U000112df',
+ '\U000112df'), ('\U000112e0', '\U000112e2'), ('\U000112e3', '\U000112e8'), ('\U00011301',
+ '\U00011301'), ('\U00011302', '\U00011303'), ('\U00011305', '\U0001130c'), ('\U0001130f',
+ '\U00011310'), ('\U00011313', '\U00011328'), ('\U0001132a', '\U00011330'), ('\U00011332',
+ '\U00011333'), ('\U00011335', '\U00011339'), ('\U0001133d', '\U0001133d'), ('\U0001133e',
+ '\U0001133f'), ('\U00011340', '\U00011340'), ('\U00011341', '\U00011344'), ('\U00011347',
+ '\U00011348'), ('\U0001134b', '\U0001134c'), ('\U00011357', '\U00011357'), ('\U0001135d',
+ '\U00011361'), ('\U00011362', '\U00011363'), ('\U00011480', '\U000114af'), ('\U000114b0',
+ '\U000114b2'), ('\U000114b3', '\U000114b8'), ('\U000114b9', '\U000114b9'), ('\U000114ba',
+ '\U000114ba'), ('\U000114bb', '\U000114be'), ('\U000114bf', '\U000114c0'), ('\U000114c1',
+ '\U000114c1'), ('\U000114c4', '\U000114c5'), ('\U000114c7', '\U000114c7'), ('\U00011580',
+ '\U000115ae'), ('\U000115af', '\U000115b1'), ('\U000115b2', '\U000115b5'), ('\U000115b8',
+ '\U000115bb'), ('\U000115bc', '\U000115bd'), ('\U000115be', '\U000115be'), ('\U00011600',
+ '\U0001162f'), ('\U00011630', '\U00011632'), ('\U00011633', '\U0001163a'), ('\U0001163b',
+ '\U0001163c'), ('\U0001163d', '\U0001163d'), ('\U0001163e', '\U0001163e'), ('\U00011640',
+ '\U00011640'), ('\U00011644', '\U00011644'), ('\U00011680', '\U000116aa'), ('\U000116ab',
+ '\U000116ab'), ('\U000116ac', '\U000116ac'), ('\U000116ad', '\U000116ad'), ('\U000116ae',
+ '\U000116af'), ('\U000116b0', '\U000116b5'), ('\U000118a0', '\U000118df'), ('\U000118ff',
+ '\U000118ff'), ('\U00011ac0', '\U00011af8'), ('\U00012000', '\U00012398'), ('\U00012400',
+ '\U0001246e'), ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'), ('\U00016a40',
+ '\U00016a5e'), ('\U00016ad0', '\U00016aed'), ('\U00016b00', '\U00016b2f'), ('\U00016b30',
+ '\U00016b36'), ('\U00016b40', '\U00016b43'), ('\U00016b63', '\U00016b77'), ('\U00016b7d',
+ '\U00016b8f'), ('\U00016f00', '\U00016f44'), ('\U00016f50', '\U00016f50'), ('\U00016f51',
+ '\U00016f7e'), ('\U00016f93', '\U00016f9f'), ('\U0001b000', '\U0001b001'), ('\U0001bc00',
+ '\U0001bc6a'), ('\U0001bc70', '\U0001bc7c'), ('\U0001bc80', '\U0001bc88'), ('\U0001bc90',
+ '\U0001bc99'), ('\U0001bc9e', '\U0001bc9e'), ('\U0001d400', '\U0001d454'), ('\U0001d456',
+ '\U0001d49c'), ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5',
+ '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b9'), ('\U0001d4bb',
+ '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d505'), ('\U0001d507',
+ '\U0001d50a'), ('\U0001d50d', '\U0001d514'), ('\U0001d516', '\U0001d51c'), ('\U0001d51e',
+ '\U0001d539'), ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'), ('\U0001d546',
+ '\U0001d546'), ('\U0001d54a', '\U0001d550'), ('\U0001d552', '\U0001d6a5'), ('\U0001d6a8',
+ '\U0001d6c0'), ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6fa'), ('\U0001d6fc',
+ '\U0001d714'), ('\U0001d716', '\U0001d734'), ('\U0001d736', '\U0001d74e'), ('\U0001d750',
+ '\U0001d76e'), ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d7a8'), ('\U0001d7aa',
+ '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb'), ('\U0001e800', '\U0001e8c4'), ('\U0001ee00',
+ '\U0001ee03'), ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'), ('\U0001ee24',
+ '\U0001ee24'), ('\U0001ee27', '\U0001ee27'), ('\U0001ee29', '\U0001ee32'), ('\U0001ee34',
+ '\U0001ee37'), ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'), ('\U0001ee42',
+ '\U0001ee42'), ('\U0001ee47', '\U0001ee47'), ('\U0001ee49', '\U0001ee49'), ('\U0001ee4b',
+ '\U0001ee4b'), ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'), ('\U0001ee54',
+ '\U0001ee54'), ('\U0001ee57', '\U0001ee57'), ('\U0001ee59', '\U0001ee59'), ('\U0001ee5b',
+ '\U0001ee5b'), ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'), ('\U0001ee61',
+ '\U0001ee62'), ('\U0001ee64', '\U0001ee64'), ('\U0001ee67', '\U0001ee6a'), ('\U0001ee6c',
+ '\U0001ee72'), ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'), ('\U0001ee7e',
+ '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'), ('\U0001ee8b', '\U0001ee9b'), ('\U0001eea1',
+ '\U0001eea3'), ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'), ('\U0001f130',
+ '\U0001f149'), ('\U0001f150', '\U0001f169'), ('\U0001f170', '\U0001f189'), ('\U00020000',
+ '\U0002a6d6'), ('\U0002a700', '\U0002b734'), ('\U0002b740', '\U0002b81d'), ('\U0002f800',
+ '\U0002fa1d')
+ ];
+
+ pub fn Alphabetic(c: char) -> bool {
+ super::bsearch_range_table(c, Alphabetic_table)
+ }
+
+ pub static Lowercase_table: &'static [(char, char)] = &[
+ ('\x61', '\x7a'), ('\xaa', '\xaa'), ('\xb5', '\xb5'), ('\xba', '\xba'), ('\xdf', '\xf6'),
+ ('\xf8', '\xff'), ('\u0101', '\u0101'), ('\u0103', '\u0103'), ('\u0105', '\u0105'),
+ ('\u0107', '\u0107'), ('\u0109', '\u0109'), ('\u010b', '\u010b'), ('\u010d', '\u010d'),
+ ('\u010f', '\u010f'), ('\u0111', '\u0111'), ('\u0113', '\u0113'), ('\u0115', '\u0115'),
+ ('\u0117', '\u0117'), ('\u0119', '\u0119'), ('\u011b', '\u011b'), ('\u011d', '\u011d'),
+ ('\u011f', '\u011f'), ('\u0121', '\u0121'), ('\u0123', '\u0123'), ('\u0125', '\u0125'),
+ ('\u0127', '\u0127'), ('\u0129', '\u0129'), ('\u012b', '\u012b'), ('\u012d', '\u012d'),
+ ('\u012f', '\u012f'), ('\u0131', '\u0131'), ('\u0133', '\u0133'), ('\u0135', '\u0135'),
+ ('\u0137', '\u0138'), ('\u013a', '\u013a'), ('\u013c', '\u013c'), ('\u013e', '\u013e'),
+ ('\u0140', '\u0140'), ('\u0142', '\u0142'), ('\u0144', '\u0144'), ('\u0146', '\u0146'),
+ ('\u0148', '\u0149'), ('\u014b', '\u014b'), ('\u014d', '\u014d'), ('\u014f', '\u014f'),
+ ('\u0151', '\u0151'), ('\u0153', '\u0153'), ('\u0155', '\u0155'), ('\u0157', '\u0157'),
+ ('\u0159', '\u0159'), ('\u015b', '\u015b'), ('\u015d', '\u015d'), ('\u015f', '\u015f'),
+ ('\u0161', '\u0161'), ('\u0163', '\u0163'), ('\u0165', '\u0165'), ('\u0167', '\u0167'),
+ ('\u0169', '\u0169'), ('\u016b', '\u016b'), ('\u016d', '\u016d'), ('\u016f', '\u016f'),
+ ('\u0171', '\u0171'), ('\u0173', '\u0173'), ('\u0175', '\u0175'), ('\u0177', '\u0177'),
+ ('\u017a', '\u017a'), ('\u017c', '\u017c'), ('\u017e', '\u0180'), ('\u0183', '\u0183'),
+ ('\u0185', '\u0185'), ('\u0188', '\u0188'), ('\u018c', '\u018d'), ('\u0192', '\u0192'),
+ ('\u0195', '\u0195'), ('\u0199', '\u019b'), ('\u019e', '\u019e'), ('\u01a1', '\u01a1'),
+ ('\u01a3', '\u01a3'), ('\u01a5', '\u01a5'), ('\u01a8', '\u01a8'), ('\u01aa', '\u01ab'),
+ ('\u01ad', '\u01ad'), ('\u01b0', '\u01b0'), ('\u01b4', '\u01b4'), ('\u01b6', '\u01b6'),
+ ('\u01b9', '\u01ba'), ('\u01bd', '\u01bf'), ('\u01c6', '\u01c6'), ('\u01c9', '\u01c9'),
+ ('\u01cc', '\u01cc'), ('\u01ce', '\u01ce'), ('\u01d0', '\u01d0'), ('\u01d2', '\u01d2'),
+ ('\u01d4', '\u01d4'), ('\u01d6', '\u01d6'), ('\u01d8', '\u01d8'), ('\u01da', '\u01da'),
+ ('\u01dc', '\u01dd'), ('\u01df', '\u01df'), ('\u01e1', '\u01e1'), ('\u01e3', '\u01e3'),
+ ('\u01e5', '\u01e5'), ('\u01e7', '\u01e7'), ('\u01e9', '\u01e9'), ('\u01eb', '\u01eb'),
+ ('\u01ed', '\u01ed'), ('\u01ef', '\u01f0'), ('\u01f3', '\u01f3'), ('\u01f5', '\u01f5'),
+ ('\u01f9', '\u01f9'), ('\u01fb', '\u01fb'), ('\u01fd', '\u01fd'), ('\u01ff', '\u01ff'),
+ ('\u0201', '\u0201'), ('\u0203', '\u0203'), ('\u0205', '\u0205'), ('\u0207', '\u0207'),
+ ('\u0209', '\u0209'), ('\u020b', '\u020b'), ('\u020d', '\u020d'), ('\u020f', '\u020f'),
+ ('\u0211', '\u0211'), ('\u0213', '\u0213'), ('\u0215', '\u0215'), ('\u0217', '\u0217'),
+ ('\u0219', '\u0219'), ('\u021b', '\u021b'), ('\u021d', '\u021d'), ('\u021f', '\u021f'),
+ ('\u0221', '\u0221'), ('\u0223', '\u0223'), ('\u0225', '\u0225'), ('\u0227', '\u0227'),
+ ('\u0229', '\u0229'), ('\u022b', '\u022b'), ('\u022d', '\u022d'), ('\u022f', '\u022f'),
+ ('\u0231', '\u0231'), ('\u0233', '\u0239'), ('\u023c', '\u023c'), ('\u023f', '\u0240'),
+ ('\u0242', '\u0242'), ('\u0247', '\u0247'), ('\u0249', '\u0249'), ('\u024b', '\u024b'),
+ ('\u024d', '\u024d'), ('\u024f', '\u0293'), ('\u0295', '\u02af'), ('\u02b0', '\u02b8'),
+ ('\u02c0', '\u02c1'), ('\u02e0', '\u02e4'), ('\u0345', '\u0345'), ('\u0371', '\u0371'),
+ ('\u0373', '\u0373'), ('\u0377', '\u0377'), ('\u037a', '\u037a'), ('\u037b', '\u037d'),
+ ('\u0390', '\u0390'), ('\u03ac', '\u03ce'), ('\u03d0', '\u03d1'), ('\u03d5', '\u03d7'),
+ ('\u03d9', '\u03d9'), ('\u03db', '\u03db'), ('\u03dd', '\u03dd'), ('\u03df', '\u03df'),
+ ('\u03e1', '\u03e1'), ('\u03e3', '\u03e3'), ('\u03e5', '\u03e5'), ('\u03e7', '\u03e7'),
+ ('\u03e9', '\u03e9'), ('\u03eb', '\u03eb'), ('\u03ed', '\u03ed'), ('\u03ef', '\u03f3'),
+ ('\u03f5', '\u03f5'), ('\u03f8', '\u03f8'), ('\u03fb', '\u03fc'), ('\u0430', '\u045f'),
+ ('\u0461', '\u0461'), ('\u0463', '\u0463'), ('\u0465', '\u0465'), ('\u0467', '\u0467'),
+ ('\u0469', '\u0469'), ('\u046b', '\u046b'), ('\u046d', '\u046d'), ('\u046f', '\u046f'),
+ ('\u0471', '\u0471'), ('\u0473', '\u0473'), ('\u0475', '\u0475'), ('\u0477', '\u0477'),
+ ('\u0479', '\u0479'), ('\u047b', '\u047b'), ('\u047d', '\u047d'), ('\u047f', '\u047f'),
+ ('\u0481', '\u0481'), ('\u048b', '\u048b'), ('\u048d', '\u048d'), ('\u048f', '\u048f'),
+ ('\u0491', '\u0491'), ('\u0493', '\u0493'), ('\u0495', '\u0495'), ('\u0497', '\u0497'),
+ ('\u0499', '\u0499'), ('\u049b', '\u049b'), ('\u049d', '\u049d'), ('\u049f', '\u049f'),
+ ('\u04a1', '\u04a1'), ('\u04a3', '\u04a3'), ('\u04a5', '\u04a5'), ('\u04a7', '\u04a7'),
+ ('\u04a9', '\u04a9'), ('\u04ab', '\u04ab'), ('\u04ad', '\u04ad'), ('\u04af', '\u04af'),
+ ('\u04b1', '\u04b1'), ('\u04b3', '\u04b3'), ('\u04b5', '\u04b5'), ('\u04b7', '\u04b7'),
+ ('\u04b9', '\u04b9'), ('\u04bb', '\u04bb'), ('\u04bd', '\u04bd'), ('\u04bf', '\u04bf'),
+ ('\u04c2', '\u04c2'), ('\u04c4', '\u04c4'), ('\u04c6', '\u04c6'), ('\u04c8', '\u04c8'),
+ ('\u04ca', '\u04ca'), ('\u04cc', '\u04cc'), ('\u04ce', '\u04cf'), ('\u04d1', '\u04d1'),
+ ('\u04d3', '\u04d3'), ('\u04d5', '\u04d5'), ('\u04d7', '\u04d7'), ('\u04d9', '\u04d9'),
+ ('\u04db', '\u04db'), ('\u04dd', '\u04dd'), ('\u04df', '\u04df'), ('\u04e1', '\u04e1'),
+ ('\u04e3', '\u04e3'), ('\u04e5', '\u04e5'), ('\u04e7', '\u04e7'), ('\u04e9', '\u04e9'),
+ ('\u04eb', '\u04eb'), ('\u04ed', '\u04ed'), ('\u04ef', '\u04ef'), ('\u04f1', '\u04f1'),
+ ('\u04f3', '\u04f3'), ('\u04f5', '\u04f5'), ('\u04f7', '\u04f7'), ('\u04f9', '\u04f9'),
+ ('\u04fb', '\u04fb'), ('\u04fd', '\u04fd'), ('\u04ff', '\u04ff'), ('\u0501', '\u0501'),
+ ('\u0503', '\u0503'), ('\u0505', '\u0505'), ('\u0507', '\u0507'), ('\u0509', '\u0509'),
+ ('\u050b', '\u050b'), ('\u050d', '\u050d'), ('\u050f', '\u050f'), ('\u0511', '\u0511'),
+ ('\u0513', '\u0513'), ('\u0515', '\u0515'), ('\u0517', '\u0517'), ('\u0519', '\u0519'),
+ ('\u051b', '\u051b'), ('\u051d', '\u051d'), ('\u051f', '\u051f'), ('\u0521', '\u0521'),
+ ('\u0523', '\u0523'), ('\u0525', '\u0525'), ('\u0527', '\u0527'), ('\u0529', '\u0529'),
+ ('\u052b', '\u052b'), ('\u052d', '\u052d'), ('\u052f', '\u052f'), ('\u0561', '\u0587'),
+ ('\u1d00', '\u1d2b'), ('\u1d2c', '\u1d6a'), ('\u1d6b', '\u1d77'), ('\u1d78', '\u1d78'),
+ ('\u1d79', '\u1d9a'), ('\u1d9b', '\u1dbf'), ('\u1e01', '\u1e01'), ('\u1e03', '\u1e03'),
+ ('\u1e05', '\u1e05'), ('\u1e07', '\u1e07'), ('\u1e09', '\u1e09'), ('\u1e0b', '\u1e0b'),
+ ('\u1e0d', '\u1e0d'), ('\u1e0f', '\u1e0f'), ('\u1e11', '\u1e11'), ('\u1e13', '\u1e13'),
+ ('\u1e15', '\u1e15'), ('\u1e17', '\u1e17'), ('\u1e19', '\u1e19'), ('\u1e1b', '\u1e1b'),
+ ('\u1e1d', '\u1e1d'), ('\u1e1f', '\u1e1f'), ('\u1e21', '\u1e21'), ('\u1e23', '\u1e23'),
+ ('\u1e25', '\u1e25'), ('\u1e27', '\u1e27'), ('\u1e29', '\u1e29'), ('\u1e2b', '\u1e2b'),
+ ('\u1e2d', '\u1e2d'), ('\u1e2f', '\u1e2f'), ('\u1e31', '\u1e31'), ('\u1e33', '\u1e33'),
+ ('\u1e35', '\u1e35'), ('\u1e37', '\u1e37'), ('\u1e39', '\u1e39'), ('\u1e3b', '\u1e3b'),
+ ('\u1e3d', '\u1e3d'), ('\u1e3f', '\u1e3f'), ('\u1e41', '\u1e41'), ('\u1e43', '\u1e43'),
+ ('\u1e45', '\u1e45'), ('\u1e47', '\u1e47'), ('\u1e49', '\u1e49'), ('\u1e4b', '\u1e4b'),
+ ('\u1e4d', '\u1e4d'), ('\u1e4f', '\u1e4f'), ('\u1e51', '\u1e51'), ('\u1e53', '\u1e53'),
+ ('\u1e55', '\u1e55'), ('\u1e57', '\u1e57'), ('\u1e59', '\u1e59'), ('\u1e5b', '\u1e5b'),
+ ('\u1e5d', '\u1e5d'), ('\u1e5f', '\u1e5f'), ('\u1e61', '\u1e61'), ('\u1e63', '\u1e63'),
+ ('\u1e65', '\u1e65'), ('\u1e67', '\u1e67'), ('\u1e69', '\u1e69'), ('\u1e6b', '\u1e6b'),
+ ('\u1e6d', '\u1e6d'), ('\u1e6f', '\u1e6f'), ('\u1e71', '\u1e71'), ('\u1e73', '\u1e73'),
+ ('\u1e75', '\u1e75'), ('\u1e77', '\u1e77'), ('\u1e79', '\u1e79'), ('\u1e7b', '\u1e7b'),
+ ('\u1e7d', '\u1e7d'), ('\u1e7f', '\u1e7f'), ('\u1e81', '\u1e81'), ('\u1e83', '\u1e83'),
+ ('\u1e85', '\u1e85'), ('\u1e87', '\u1e87'), ('\u1e89', '\u1e89'), ('\u1e8b', '\u1e8b'),
+ ('\u1e8d', '\u1e8d'), ('\u1e8f', '\u1e8f'), ('\u1e91', '\u1e91'), ('\u1e93', '\u1e93'),
+ ('\u1e95', '\u1e9d'), ('\u1e9f', '\u1e9f'), ('\u1ea1', '\u1ea1'), ('\u1ea3', '\u1ea3'),
+ ('\u1ea5', '\u1ea5'), ('\u1ea7', '\u1ea7'), ('\u1ea9', '\u1ea9'), ('\u1eab', '\u1eab'),
+ ('\u1ead', '\u1ead'), ('\u1eaf', '\u1eaf'), ('\u1eb1', '\u1eb1'), ('\u1eb3', '\u1eb3'),
+ ('\u1eb5', '\u1eb5'), ('\u1eb7', '\u1eb7'), ('\u1eb9', '\u1eb9'), ('\u1ebb', '\u1ebb'),
+ ('\u1ebd', '\u1ebd'), ('\u1ebf', '\u1ebf'), ('\u1ec1', '\u1ec1'), ('\u1ec3', '\u1ec3'),
+ ('\u1ec5', '\u1ec5'), ('\u1ec7', '\u1ec7'), ('\u1ec9', '\u1ec9'), ('\u1ecb', '\u1ecb'),
+ ('\u1ecd', '\u1ecd'), ('\u1ecf', '\u1ecf'), ('\u1ed1', '\u1ed1'), ('\u1ed3', '\u1ed3'),
+ ('\u1ed5', '\u1ed5'), ('\u1ed7', '\u1ed7'), ('\u1ed9', '\u1ed9'), ('\u1edb', '\u1edb'),
+ ('\u1edd', '\u1edd'), ('\u1edf', '\u1edf'), ('\u1ee1', '\u1ee1'), ('\u1ee3', '\u1ee3'),
+ ('\u1ee5', '\u1ee5'), ('\u1ee7', '\u1ee7'), ('\u1ee9', '\u1ee9'), ('\u1eeb', '\u1eeb'),
+ ('\u1eed', '\u1eed'), ('\u1eef', '\u1eef'), ('\u1ef1', '\u1ef1'), ('\u1ef3', '\u1ef3'),
+ ('\u1ef5', '\u1ef5'), ('\u1ef7', '\u1ef7'), ('\u1ef9', '\u1ef9'), ('\u1efb', '\u1efb'),
+ ('\u1efd', '\u1efd'), ('\u1eff', '\u1f07'), ('\u1f10', '\u1f15'), ('\u1f20', '\u1f27'),
+ ('\u1f30', '\u1f37'), ('\u1f40', '\u1f45'), ('\u1f50', '\u1f57'), ('\u1f60', '\u1f67'),
+ ('\u1f70', '\u1f7d'), ('\u1f80', '\u1f87'), ('\u1f90', '\u1f97'), ('\u1fa0', '\u1fa7'),
+ ('\u1fb0', '\u1fb4'), ('\u1fb6', '\u1fb7'), ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'),
+ ('\u1fc6', '\u1fc7'), ('\u1fd0', '\u1fd3'), ('\u1fd6', '\u1fd7'), ('\u1fe0', '\u1fe7'),
+ ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ff7'), ('\u2071', '\u2071'), ('\u207f', '\u207f'),
+ ('\u2090', '\u209c'), ('\u210a', '\u210a'), ('\u210e', '\u210f'), ('\u2113', '\u2113'),
+ ('\u212f', '\u212f'), ('\u2134', '\u2134'), ('\u2139', '\u2139'), ('\u213c', '\u213d'),
+ ('\u2146', '\u2149'), ('\u214e', '\u214e'), ('\u2170', '\u217f'), ('\u2184', '\u2184'),
+ ('\u24d0', '\u24e9'), ('\u2c30', '\u2c5e'), ('\u2c61', '\u2c61'), ('\u2c65', '\u2c66'),
+ ('\u2c68', '\u2c68'), ('\u2c6a', '\u2c6a'), ('\u2c6c', '\u2c6c'), ('\u2c71', '\u2c71'),
+ ('\u2c73', '\u2c74'), ('\u2c76', '\u2c7b'), ('\u2c7c', '\u2c7d'), ('\u2c81', '\u2c81'),
+ ('\u2c83', '\u2c83'), ('\u2c85', '\u2c85'), ('\u2c87', '\u2c87'), ('\u2c89', '\u2c89'),
+ ('\u2c8b', '\u2c8b'), ('\u2c8d', '\u2c8d'), ('\u2c8f', '\u2c8f'), ('\u2c91', '\u2c91'),
+ ('\u2c93', '\u2c93'), ('\u2c95', '\u2c95'), ('\u2c97', '\u2c97'), ('\u2c99', '\u2c99'),
+ ('\u2c9b', '\u2c9b'), ('\u2c9d', '\u2c9d'), ('\u2c9f', '\u2c9f'), ('\u2ca1', '\u2ca1'),
+ ('\u2ca3', '\u2ca3'), ('\u2ca5', '\u2ca5'), ('\u2ca7', '\u2ca7'), ('\u2ca9', '\u2ca9'),
+ ('\u2cab', '\u2cab'), ('\u2cad', '\u2cad'), ('\u2caf', '\u2caf'), ('\u2cb1', '\u2cb1'),
+ ('\u2cb3', '\u2cb3'), ('\u2cb5', '\u2cb5'), ('\u2cb7', '\u2cb7'), ('\u2cb9', '\u2cb9'),
+ ('\u2cbb', '\u2cbb'), ('\u2cbd', '\u2cbd'), ('\u2cbf', '\u2cbf'), ('\u2cc1', '\u2cc1'),
+ ('\u2cc3', '\u2cc3'), ('\u2cc5', '\u2cc5'), ('\u2cc7', '\u2cc7'), ('\u2cc9', '\u2cc9'),
+ ('\u2ccb', '\u2ccb'), ('\u2ccd', '\u2ccd'), ('\u2ccf', '\u2ccf'), ('\u2cd1', '\u2cd1'),
+ ('\u2cd3', '\u2cd3'), ('\u2cd5', '\u2cd5'), ('\u2cd7', '\u2cd7'), ('\u2cd9', '\u2cd9'),
+ ('\u2cdb', '\u2cdb'), ('\u2cdd', '\u2cdd'), ('\u2cdf', '\u2cdf'), ('\u2ce1', '\u2ce1'),
+ ('\u2ce3', '\u2ce4'), ('\u2cec', '\u2cec'), ('\u2cee', '\u2cee'), ('\u2cf3', '\u2cf3'),
+ ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'), ('\ua641', '\ua641'),
+ ('\ua643', '\ua643'), ('\ua645', '\ua645'), ('\ua647', '\ua647'), ('\ua649', '\ua649'),
+ ('\ua64b', '\ua64b'), ('\ua64d', '\ua64d'), ('\ua64f', '\ua64f'), ('\ua651', '\ua651'),
+ ('\ua653', '\ua653'), ('\ua655', '\ua655'), ('\ua657', '\ua657'), ('\ua659', '\ua659'),
+ ('\ua65b', '\ua65b'), ('\ua65d', '\ua65d'), ('\ua65f', '\ua65f'), ('\ua661', '\ua661'),
+ ('\ua663', '\ua663'), ('\ua665', '\ua665'), ('\ua667', '\ua667'), ('\ua669', '\ua669'),
+ ('\ua66b', '\ua66b'), ('\ua66d', '\ua66d'), ('\ua681', '\ua681'), ('\ua683', '\ua683'),
+ ('\ua685', '\ua685'), ('\ua687', '\ua687'), ('\ua689', '\ua689'), ('\ua68b', '\ua68b'),
+ ('\ua68d', '\ua68d'), ('\ua68f', '\ua68f'), ('\ua691', '\ua691'), ('\ua693', '\ua693'),
+ ('\ua695', '\ua695'), ('\ua697', '\ua697'), ('\ua699', '\ua699'), ('\ua69b', '\ua69b'),
+ ('\ua69c', '\ua69d'), ('\ua723', '\ua723'), ('\ua725', '\ua725'), ('\ua727', '\ua727'),
+ ('\ua729', '\ua729'), ('\ua72b', '\ua72b'), ('\ua72d', '\ua72d'), ('\ua72f', '\ua731'),
+ ('\ua733', '\ua733'), ('\ua735', '\ua735'), ('\ua737', '\ua737'), ('\ua739', '\ua739'),
+ ('\ua73b', '\ua73b'), ('\ua73d', '\ua73d'), ('\ua73f', '\ua73f'), ('\ua741', '\ua741'),
+ ('\ua743', '\ua743'), ('\ua745', '\ua745'), ('\ua747', '\ua747'), ('\ua749', '\ua749'),
+ ('\ua74b', '\ua74b'), ('\ua74d', '\ua74d'), ('\ua74f', '\ua74f'), ('\ua751', '\ua751'),
+ ('\ua753', '\ua753'), ('\ua755', '\ua755'), ('\ua757', '\ua757'), ('\ua759', '\ua759'),
+ ('\ua75b', '\ua75b'), ('\ua75d', '\ua75d'), ('\ua75f', '\ua75f'), ('\ua761', '\ua761'),
+ ('\ua763', '\ua763'), ('\ua765', '\ua765'), ('\ua767', '\ua767'), ('\ua769', '\ua769'),
+ ('\ua76b', '\ua76b'), ('\ua76d', '\ua76d'), ('\ua76f', '\ua76f'), ('\ua770', '\ua770'),
+ ('\ua771', '\ua778'), ('\ua77a', '\ua77a'), ('\ua77c', '\ua77c'), ('\ua77f', '\ua77f'),
+ ('\ua781', '\ua781'), ('\ua783', '\ua783'), ('\ua785', '\ua785'), ('\ua787', '\ua787'),
+ ('\ua78c', '\ua78c'), ('\ua78e', '\ua78e'), ('\ua791', '\ua791'), ('\ua793', '\ua795'),
+ ('\ua797', '\ua797'), ('\ua799', '\ua799'), ('\ua79b', '\ua79b'), ('\ua79d', '\ua79d'),
+ ('\ua79f', '\ua79f'), ('\ua7a1', '\ua7a1'), ('\ua7a3', '\ua7a3'), ('\ua7a5', '\ua7a5'),
+ ('\ua7a7', '\ua7a7'), ('\ua7a9', '\ua7a9'), ('\ua7f8', '\ua7f9'), ('\ua7fa', '\ua7fa'),
+ ('\uab30', '\uab5a'), ('\uab5c', '\uab5f'), ('\uab64', '\uab65'), ('\ufb00', '\ufb06'),
+ ('\ufb13', '\ufb17'), ('\uff41', '\uff5a'), ('\U00010428', '\U0001044f'), ('\U000118c0',
+ '\U000118df'), ('\U0001d41a', '\U0001d433'), ('\U0001d44e', '\U0001d454'), ('\U0001d456',
+ '\U0001d467'), ('\U0001d482', '\U0001d49b'), ('\U0001d4b6', '\U0001d4b9'), ('\U0001d4bb',
+ '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d4cf'), ('\U0001d4ea',
+ '\U0001d503'), ('\U0001d51e', '\U0001d537'), ('\U0001d552', '\U0001d56b'), ('\U0001d586',
+ '\U0001d59f'), ('\U0001d5ba', '\U0001d5d3'), ('\U0001d5ee', '\U0001d607'), ('\U0001d622',
+ '\U0001d63b'), ('\U0001d656', '\U0001d66f'), ('\U0001d68a', '\U0001d6a5'), ('\U0001d6c2',
+ '\U0001d6da'), ('\U0001d6dc', '\U0001d6e1'), ('\U0001d6fc', '\U0001d714'), ('\U0001d716',
+ '\U0001d71b'), ('\U0001d736', '\U0001d74e'), ('\U0001d750', '\U0001d755'), ('\U0001d770',
+ '\U0001d788'), ('\U0001d78a', '\U0001d78f'), ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4',
+ '\U0001d7c9'), ('\U0001d7cb', '\U0001d7cb')
+ ];
+
+ pub fn Lowercase(c: char) -> bool {
+ super::bsearch_range_table(c, Lowercase_table)
+ }
+
+ pub static Uppercase_table: &'static [(char, char)] = &[
+ ('\x41', '\x5a'), ('\xc0', '\xd6'), ('\xd8', '\xde'), ('\u0100', '\u0100'), ('\u0102',
+ '\u0102'), ('\u0104', '\u0104'), ('\u0106', '\u0106'), ('\u0108', '\u0108'), ('\u010a',
+ '\u010a'), ('\u010c', '\u010c'), ('\u010e', '\u010e'), ('\u0110', '\u0110'), ('\u0112',
+ '\u0112'), ('\u0114', '\u0114'), ('\u0116', '\u0116'), ('\u0118', '\u0118'), ('\u011a',
+ '\u011a'), ('\u011c', '\u011c'), ('\u011e', '\u011e'), ('\u0120', '\u0120'), ('\u0122',
+ '\u0122'), ('\u0124', '\u0124'), ('\u0126', '\u0126'), ('\u0128', '\u0128'), ('\u012a',
+ '\u012a'), ('\u012c', '\u012c'), ('\u012e', '\u012e'), ('\u0130', '\u0130'), ('\u0132',
+ '\u0132'), ('\u0134', '\u0134'), ('\u0136', '\u0136'), ('\u0139', '\u0139'), ('\u013b',
+ '\u013b'), ('\u013d', '\u013d'), ('\u013f', '\u013f'), ('\u0141', '\u0141'), ('\u0143',
+ '\u0143'), ('\u0145', '\u0145'), ('\u0147', '\u0147'), ('\u014a', '\u014a'), ('\u014c',
+ '\u014c'), ('\u014e', '\u014e'), ('\u0150', '\u0150'), ('\u0152', '\u0152'), ('\u0154',
+ '\u0154'), ('\u0156', '\u0156'), ('\u0158', '\u0158'), ('\u015a', '\u015a'), ('\u015c',
+ '\u015c'), ('\u015e', '\u015e'), ('\u0160', '\u0160'), ('\u0162', '\u0162'), ('\u0164',
+ '\u0164'), ('\u0166', '\u0166'), ('\u0168', '\u0168'), ('\u016a', '\u016a'), ('\u016c',
+ '\u016c'), ('\u016e', '\u016e'), ('\u0170', '\u0170'), ('\u0172', '\u0172'), ('\u0174',
+ '\u0174'), ('\u0176', '\u0176'), ('\u0178', '\u0179'), ('\u017b', '\u017b'), ('\u017d',
+ '\u017d'), ('\u0181', '\u0182'), ('\u0184', '\u0184'), ('\u0186', '\u0187'), ('\u0189',
+ '\u018b'), ('\u018e', '\u0191'), ('\u0193', '\u0194'), ('\u0196', '\u0198'), ('\u019c',
+ '\u019d'), ('\u019f', '\u01a0'), ('\u01a2', '\u01a2'), ('\u01a4', '\u01a4'), ('\u01a6',
+ '\u01a7'), ('\u01a9', '\u01a9'), ('\u01ac', '\u01ac'), ('\u01ae', '\u01af'), ('\u01b1',
+ '\u01b3'), ('\u01b5', '\u01b5'), ('\u01b7', '\u01b8'), ('\u01bc', '\u01bc'), ('\u01c4',
+ '\u01c4'), ('\u01c7', '\u01c7'), ('\u01ca', '\u01ca'), ('\u01cd', '\u01cd'), ('\u01cf',
+ '\u01cf'), ('\u01d1', '\u01d1'), ('\u01d3', '\u01d3'), ('\u01d5', '\u01d5'), ('\u01d7',
+ '\u01d7'), ('\u01d9', '\u01d9'), ('\u01db', '\u01db'), ('\u01de', '\u01de'), ('\u01e0',
+ '\u01e0'), ('\u01e2', '\u01e2'), ('\u01e4', '\u01e4'), ('\u01e6', '\u01e6'), ('\u01e8',
+ '\u01e8'), ('\u01ea', '\u01ea'), ('\u01ec', '\u01ec'), ('\u01ee', '\u01ee'), ('\u01f1',
+ '\u01f1'), ('\u01f4', '\u01f4'), ('\u01f6', '\u01f8'), ('\u01fa', '\u01fa'), ('\u01fc',
+ '\u01fc'), ('\u01fe', '\u01fe'), ('\u0200', '\u0200'), ('\u0202', '\u0202'), ('\u0204',
+ '\u0204'), ('\u0206', '\u0206'), ('\u0208', '\u0208'), ('\u020a', '\u020a'), ('\u020c',
+ '\u020c'), ('\u020e', '\u020e'), ('\u0210', '\u0210'), ('\u0212', '\u0212'), ('\u0214',
+ '\u0214'), ('\u0216', '\u0216'), ('\u0218', '\u0218'), ('\u021a', '\u021a'), ('\u021c',
+ '\u021c'), ('\u021e', '\u021e'), ('\u0220', '\u0220'), ('\u0222', '\u0222'), ('\u0224',
+ '\u0224'), ('\u0226', '\u0226'), ('\u0228', '\u0228'), ('\u022a', '\u022a'), ('\u022c',
+ '\u022c'), ('\u022e', '\u022e'), ('\u0230', '\u0230'), ('\u0232', '\u0232'), ('\u023a',
+ '\u023b'), ('\u023d', '\u023e'), ('\u0241', '\u0241'), ('\u0243', '\u0246'), ('\u0248',
+ '\u0248'), ('\u024a', '\u024a'), ('\u024c', '\u024c'), ('\u024e', '\u024e'), ('\u0370',
+ '\u0370'), ('\u0372', '\u0372'), ('\u0376', '\u0376'), ('\u037f', '\u037f'), ('\u0386',
+ '\u0386'), ('\u0388', '\u038a'), ('\u038c', '\u038c'), ('\u038e', '\u038f'), ('\u0391',
+ '\u03a1'), ('\u03a3', '\u03ab'), ('\u03cf', '\u03cf'), ('\u03d2', '\u03d4'), ('\u03d8',
+ '\u03d8'), ('\u03da', '\u03da'), ('\u03dc', '\u03dc'), ('\u03de', '\u03de'), ('\u03e0',
+ '\u03e0'), ('\u03e2', '\u03e2'), ('\u03e4', '\u03e4'), ('\u03e6', '\u03e6'), ('\u03e8',
+ '\u03e8'), ('\u03ea', '\u03ea'), ('\u03ec', '\u03ec'), ('\u03ee', '\u03ee'), ('\u03f4',
+ '\u03f4'), ('\u03f7', '\u03f7'), ('\u03f9', '\u03fa'), ('\u03fd', '\u042f'), ('\u0460',
+ '\u0460'), ('\u0462', '\u0462'), ('\u0464', '\u0464'), ('\u0466', '\u0466'), ('\u0468',
+ '\u0468'), ('\u046a', '\u046a'), ('\u046c', '\u046c'), ('\u046e', '\u046e'), ('\u0470',
+ '\u0470'), ('\u0472', '\u0472'), ('\u0474', '\u0474'), ('\u0476', '\u0476'), ('\u0478',
+ '\u0478'), ('\u047a', '\u047a'), ('\u047c', '\u047c'), ('\u047e', '\u047e'), ('\u0480',
+ '\u0480'), ('\u048a', '\u048a'), ('\u048c', '\u048c'), ('\u048e', '\u048e'), ('\u0490',
+ '\u0490'), ('\u0492', '\u0492'), ('\u0494', '\u0494'), ('\u0496', '\u0496'), ('\u0498',
+ '\u0498'), ('\u049a', '\u049a'), ('\u049c', '\u049c'), ('\u049e', '\u049e'), ('\u04a0',
+ '\u04a0'), ('\u04a2', '\u04a2'), ('\u04a4', '\u04a4'), ('\u04a6', '\u04a6'), ('\u04a8',
+ '\u04a8'), ('\u04aa', '\u04aa'), ('\u04ac', '\u04ac'), ('\u04ae', '\u04ae'), ('\u04b0',
+ '\u04b0'), ('\u04b2', '\u04b2'), ('\u04b4', '\u04b4'), ('\u04b6', '\u04b6'), ('\u04b8',
+ '\u04b8'), ('\u04ba', '\u04ba'), ('\u04bc', '\u04bc'), ('\u04be', '\u04be'), ('\u04c0',
+ '\u04c1'), ('\u04c3', '\u04c3'), ('\u04c5', '\u04c5'), ('\u04c7', '\u04c7'), ('\u04c9',
+ '\u04c9'), ('\u04cb', '\u04cb'), ('\u04cd', '\u04cd'), ('\u04d0', '\u04d0'), ('\u04d2',
+ '\u04d2'), ('\u04d4', '\u04d4'), ('\u04d6', '\u04d6'), ('\u04d8', '\u04d8'), ('\u04da',
+ '\u04da'), ('\u04dc', '\u04dc'), ('\u04de', '\u04de'), ('\u04e0', '\u04e0'), ('\u04e2',
+ '\u04e2'), ('\u04e4', '\u04e4'), ('\u04e6', '\u04e6'), ('\u04e8', '\u04e8'), ('\u04ea',
+ '\u04ea'), ('\u04ec', '\u04ec'), ('\u04ee', '\u04ee'), ('\u04f0', '\u04f0'), ('\u04f2',
+ '\u04f2'), ('\u04f4', '\u04f4'), ('\u04f6', '\u04f6'), ('\u04f8', '\u04f8'), ('\u04fa',
+ '\u04fa'), ('\u04fc', '\u04fc'), ('\u04fe', '\u04fe'), ('\u0500', '\u0500'), ('\u0502',
+ '\u0502'), ('\u0504', '\u0504'), ('\u0506', '\u0506'), ('\u0508', '\u0508'), ('\u050a',
+ '\u050a'), ('\u050c', '\u050c'), ('\u050e', '\u050e'), ('\u0510', '\u0510'), ('\u0512',
+ '\u0512'), ('\u0514', '\u0514'), ('\u0516', '\u0516'), ('\u0518', '\u0518'), ('\u051a',
+ '\u051a'), ('\u051c', '\u051c'), ('\u051e', '\u051e'), ('\u0520', '\u0520'), ('\u0522',
+ '\u0522'), ('\u0524', '\u0524'), ('\u0526', '\u0526'), ('\u0528', '\u0528'), ('\u052a',
+ '\u052a'), ('\u052c', '\u052c'), ('\u052e', '\u052e'), ('\u0531', '\u0556'), ('\u10a0',
+ '\u10c5'), ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'), ('\u1e00', '\u1e00'), ('\u1e02',
+ '\u1e02'), ('\u1e04', '\u1e04'), ('\u1e06', '\u1e06'), ('\u1e08', '\u1e08'), ('\u1e0a',
+ '\u1e0a'), ('\u1e0c', '\u1e0c'), ('\u1e0e', '\u1e0e'), ('\u1e10', '\u1e10'), ('\u1e12',
+ '\u1e12'), ('\u1e14', '\u1e14'), ('\u1e16', '\u1e16'), ('\u1e18', '\u1e18'), ('\u1e1a',
+ '\u1e1a'), ('\u1e1c', '\u1e1c'), ('\u1e1e', '\u1e1e'), ('\u1e20', '\u1e20'), ('\u1e22',
+ '\u1e22'), ('\u1e24', '\u1e24'), ('\u1e26', '\u1e26'), ('\u1e28', '\u1e28'), ('\u1e2a',
+ '\u1e2a'), ('\u1e2c', '\u1e2c'), ('\u1e2e', '\u1e2e'), ('\u1e30', '\u1e30'), ('\u1e32',
+ '\u1e32'), ('\u1e34', '\u1e34'), ('\u1e36', '\u1e36'), ('\u1e38', '\u1e38'), ('\u1e3a',
+ '\u1e3a'), ('\u1e3c', '\u1e3c'), ('\u1e3e', '\u1e3e'), ('\u1e40', '\u1e40'), ('\u1e42',
+ '\u1e42'), ('\u1e44', '\u1e44'), ('\u1e46', '\u1e46'), ('\u1e48', '\u1e48'), ('\u1e4a',
+ '\u1e4a'), ('\u1e4c', '\u1e4c'), ('\u1e4e', '\u1e4e'), ('\u1e50', '\u1e50'), ('\u1e52',
+ '\u1e52'), ('\u1e54', '\u1e54'), ('\u1e56', '\u1e56'), ('\u1e58', '\u1e58'), ('\u1e5a',
+ '\u1e5a'), ('\u1e5c', '\u1e5c'), ('\u1e5e', '\u1e5e'), ('\u1e60', '\u1e60'), ('\u1e62',
+ '\u1e62'), ('\u1e64', '\u1e64'), ('\u1e66', '\u1e66'), ('\u1e68', '\u1e68'), ('\u1e6a',
+ '\u1e6a'), ('\u1e6c', '\u1e6c'), ('\u1e6e', '\u1e6e'), ('\u1e70', '\u1e70'), ('\u1e72',
+ '\u1e72'), ('\u1e74', '\u1e74'), ('\u1e76', '\u1e76'), ('\u1e78', '\u1e78'), ('\u1e7a',
+ '\u1e7a'), ('\u1e7c', '\u1e7c'), ('\u1e7e', '\u1e7e'), ('\u1e80', '\u1e80'), ('\u1e82',
+ '\u1e82'), ('\u1e84', '\u1e84'), ('\u1e86', '\u1e86'), ('\u1e88', '\u1e88'), ('\u1e8a',
+ '\u1e8a'), ('\u1e8c', '\u1e8c'), ('\u1e8e', '\u1e8e'), ('\u1e90', '\u1e90'), ('\u1e92',
+ '\u1e92'), ('\u1e94', '\u1e94'), ('\u1e9e', '\u1e9e'), ('\u1ea0', '\u1ea0'), ('\u1ea2',
+ '\u1ea2'), ('\u1ea4', '\u1ea4'), ('\u1ea6', '\u1ea6'), ('\u1ea8', '\u1ea8'), ('\u1eaa',
+ '\u1eaa'), ('\u1eac', '\u1eac'), ('\u1eae', '\u1eae'), ('\u1eb0', '\u1eb0'), ('\u1eb2',
+ '\u1eb2'), ('\u1eb4', '\u1eb4'), ('\u1eb6', '\u1eb6'), ('\u1eb8', '\u1eb8'), ('\u1eba',
+ '\u1eba'), ('\u1ebc', '\u1ebc'), ('\u1ebe', '\u1ebe'), ('\u1ec0', '\u1ec0'), ('\u1ec2',
+ '\u1ec2'), ('\u1ec4', '\u1ec4'), ('\u1ec6', '\u1ec6'), ('\u1ec8', '\u1ec8'), ('\u1eca',
+ '\u1eca'), ('\u1ecc', '\u1ecc'), ('\u1ece', '\u1ece'), ('\u1ed0', '\u1ed0'), ('\u1ed2',
+ '\u1ed2'), ('\u1ed4', '\u1ed4'), ('\u1ed6', '\u1ed6'), ('\u1ed8', '\u1ed8'), ('\u1eda',
+ '\u1eda'), ('\u1edc', '\u1edc'), ('\u1ede', '\u1ede'), ('\u1ee0', '\u1ee0'), ('\u1ee2',
+ '\u1ee2'), ('\u1ee4', '\u1ee4'), ('\u1ee6', '\u1ee6'), ('\u1ee8', '\u1ee8'), ('\u1eea',
+ '\u1eea'), ('\u1eec', '\u1eec'), ('\u1eee', '\u1eee'), ('\u1ef0', '\u1ef0'), ('\u1ef2',
+ '\u1ef2'), ('\u1ef4', '\u1ef4'), ('\u1ef6', '\u1ef6'), ('\u1ef8', '\u1ef8'), ('\u1efa',
+ '\u1efa'), ('\u1efc', '\u1efc'), ('\u1efe', '\u1efe'), ('\u1f08', '\u1f0f'), ('\u1f18',
+ '\u1f1d'), ('\u1f28', '\u1f2f'), ('\u1f38', '\u1f3f'), ('\u1f48', '\u1f4d'), ('\u1f59',
+ '\u1f59'), ('\u1f5b', '\u1f5b'), ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f5f'), ('\u1f68',
+ '\u1f6f'), ('\u1fb8', '\u1fbb'), ('\u1fc8', '\u1fcb'), ('\u1fd8', '\u1fdb'), ('\u1fe8',
+ '\u1fec'), ('\u1ff8', '\u1ffb'), ('\u2102', '\u2102'), ('\u2107', '\u2107'), ('\u210b',
+ '\u210d'), ('\u2110', '\u2112'), ('\u2115', '\u2115'), ('\u2119', '\u211d'), ('\u2124',
+ '\u2124'), ('\u2126', '\u2126'), ('\u2128', '\u2128'), ('\u212a', '\u212d'), ('\u2130',
+ '\u2133'), ('\u213e', '\u213f'), ('\u2145', '\u2145'), ('\u2160', '\u216f'), ('\u2183',
+ '\u2183'), ('\u24b6', '\u24cf'), ('\u2c00', '\u2c2e'), ('\u2c60', '\u2c60'), ('\u2c62',
+ '\u2c64'), ('\u2c67', '\u2c67'), ('\u2c69', '\u2c69'), ('\u2c6b', '\u2c6b'), ('\u2c6d',
+ '\u2c70'), ('\u2c72', '\u2c72'), ('\u2c75', '\u2c75'), ('\u2c7e', '\u2c80'), ('\u2c82',
+ '\u2c82'), ('\u2c84', '\u2c84'), ('\u2c86', '\u2c86'), ('\u2c88', '\u2c88'), ('\u2c8a',
+ '\u2c8a'), ('\u2c8c', '\u2c8c'), ('\u2c8e', '\u2c8e'), ('\u2c90', '\u2c90'), ('\u2c92',
+ '\u2c92'), ('\u2c94', '\u2c94'), ('\u2c96', '\u2c96'), ('\u2c98', '\u2c98'), ('\u2c9a',
+ '\u2c9a'), ('\u2c9c', '\u2c9c'), ('\u2c9e', '\u2c9e'), ('\u2ca0', '\u2ca0'), ('\u2ca2',
+ '\u2ca2'), ('\u2ca4', '\u2ca4'), ('\u2ca6', '\u2ca6'), ('\u2ca8', '\u2ca8'), ('\u2caa',
+ '\u2caa'), ('\u2cac', '\u2cac'), ('\u2cae', '\u2cae'), ('\u2cb0', '\u2cb0'), ('\u2cb2',
+ '\u2cb2'), ('\u2cb4', '\u2cb4'), ('\u2cb6', '\u2cb6'), ('\u2cb8', '\u2cb8'), ('\u2cba',
+ '\u2cba'), ('\u2cbc', '\u2cbc'), ('\u2cbe', '\u2cbe'), ('\u2cc0', '\u2cc0'), ('\u2cc2',
+ '\u2cc2'), ('\u2cc4', '\u2cc4'), ('\u2cc6', '\u2cc6'), ('\u2cc8', '\u2cc8'), ('\u2cca',
+ '\u2cca'), ('\u2ccc', '\u2ccc'), ('\u2cce', '\u2cce'), ('\u2cd0', '\u2cd0'), ('\u2cd2',
+ '\u2cd2'), ('\u2cd4', '\u2cd4'), ('\u2cd6', '\u2cd6'), ('\u2cd8', '\u2cd8'), ('\u2cda',
+ '\u2cda'), ('\u2cdc', '\u2cdc'), ('\u2cde', '\u2cde'), ('\u2ce0', '\u2ce0'), ('\u2ce2',
+ '\u2ce2'), ('\u2ceb', '\u2ceb'), ('\u2ced', '\u2ced'), ('\u2cf2', '\u2cf2'), ('\ua640',
+ '\ua640'), ('\ua642', '\ua642'), ('\ua644', '\ua644'), ('\ua646', '\ua646'), ('\ua648',
+ '\ua648'), ('\ua64a', '\ua64a'), ('\ua64c', '\ua64c'), ('\ua64e', '\ua64e'), ('\ua650',
+ '\ua650'), ('\ua652', '\ua652'), ('\ua654', '\ua654'), ('\ua656', '\ua656'), ('\ua658',
+ '\ua658'), ('\ua65a', '\ua65a'), ('\ua65c', '\ua65c'), ('\ua65e', '\ua65e'), ('\ua660',
+ '\ua660'), ('\ua662', '\ua662'), ('\ua664', '\ua664'), ('\ua666', '\ua666'), ('\ua668',
+ '\ua668'), ('\ua66a', '\ua66a'), ('\ua66c', '\ua66c'), ('\ua680', '\ua680'), ('\ua682',
+ '\ua682'), ('\ua684', '\ua684'), ('\ua686', '\ua686'), ('\ua688', '\ua688'), ('\ua68a',
+ '\ua68a'), ('\ua68c', '\ua68c'), ('\ua68e', '\ua68e'), ('\ua690', '\ua690'), ('\ua692',
+ '\ua692'), ('\ua694', '\ua694'), ('\ua696', '\ua696'), ('\ua698', '\ua698'), ('\ua69a',
+ '\ua69a'), ('\ua722', '\ua722'), ('\ua724', '\ua724'), ('\ua726', '\ua726'), ('\ua728',
+ '\ua728'), ('\ua72a', '\ua72a'), ('\ua72c', '\ua72c'), ('\ua72e', '\ua72e'), ('\ua732',
+ '\ua732'), ('\ua734', '\ua734'), ('\ua736', '\ua736'), ('\ua738', '\ua738'), ('\ua73a',
+ '\ua73a'), ('\ua73c', '\ua73c'), ('\ua73e', '\ua73e'), ('\ua740', '\ua740'), ('\ua742',
+ '\ua742'), ('\ua744', '\ua744'), ('\ua746', '\ua746'), ('\ua748', '\ua748'), ('\ua74a',
+ '\ua74a'), ('\ua74c', '\ua74c'), ('\ua74e', '\ua74e'), ('\ua750', '\ua750'), ('\ua752',
+ '\ua752'), ('\ua754', '\ua754'), ('\ua756', '\ua756'), ('\ua758', '\ua758'), ('\ua75a',
+ '\ua75a'), ('\ua75c', '\ua75c'), ('\ua75e', '\ua75e'), ('\ua760', '\ua760'), ('\ua762',
+ '\ua762'), ('\ua764', '\ua764'), ('\ua766', '\ua766'), ('\ua768', '\ua768'), ('\ua76a',
+ '\ua76a'), ('\ua76c', '\ua76c'), ('\ua76e', '\ua76e'), ('\ua779', '\ua779'), ('\ua77b',
+ '\ua77b'), ('\ua77d', '\ua77e'), ('\ua780', '\ua780'), ('\ua782', '\ua782'), ('\ua784',
+ '\ua784'), ('\ua786', '\ua786'), ('\ua78b', '\ua78b'), ('\ua78d', '\ua78d'), ('\ua790',
+ '\ua790'), ('\ua792', '\ua792'), ('\ua796', '\ua796'), ('\ua798', '\ua798'), ('\ua79a',
+ '\ua79a'), ('\ua79c', '\ua79c'), ('\ua79e', '\ua79e'), ('\ua7a0', '\ua7a0'), ('\ua7a2',
+ '\ua7a2'), ('\ua7a4', '\ua7a4'), ('\ua7a6', '\ua7a6'), ('\ua7a8', '\ua7a8'), ('\ua7aa',
+ '\ua7ad'), ('\ua7b0', '\ua7b1'), ('\uff21', '\uff3a'), ('\U00010400', '\U00010427'),
+ ('\U000118a0', '\U000118bf'), ('\U0001d400', '\U0001d419'), ('\U0001d434', '\U0001d44d'),
+ ('\U0001d468', '\U0001d481'), ('\U0001d49c', '\U0001d49c'), ('\U0001d49e', '\U0001d49f'),
+ ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5', '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'),
+ ('\U0001d4ae', '\U0001d4b5'), ('\U0001d4d0', '\U0001d4e9'), ('\U0001d504', '\U0001d505'),
+ ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'), ('\U0001d516', '\U0001d51c'),
+ ('\U0001d538', '\U0001d539'), ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'),
+ ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'), ('\U0001d56c', '\U0001d585'),
+ ('\U0001d5a0', '\U0001d5b9'), ('\U0001d5d4', '\U0001d5ed'), ('\U0001d608', '\U0001d621'),
+ ('\U0001d63c', '\U0001d655'), ('\U0001d670', '\U0001d689'), ('\U0001d6a8', '\U0001d6c0'),
+ ('\U0001d6e2', '\U0001d6fa'), ('\U0001d71c', '\U0001d734'), ('\U0001d756', '\U0001d76e'),
+ ('\U0001d790', '\U0001d7a8'), ('\U0001d7ca', '\U0001d7ca'), ('\U0001f130', '\U0001f149'),
+ ('\U0001f150', '\U0001f169'), ('\U0001f170', '\U0001f189')
+ ];
+
+ pub fn Uppercase(c: char) -> bool {
+ super::bsearch_range_table(c, Uppercase_table)
+ }
+
+ pub static XID_Continue_table: &'static [(char, char)] = &[
+ ('\x30', '\x39'), ('\x41', '\x5a'), ('\x5f', '\x5f'), ('\x61', '\x7a'), ('\xaa', '\xaa'),
+ ('\xb5', '\xb5'), ('\xb7', '\xb7'), ('\xba', '\xba'), ('\xc0', '\xd6'), ('\xd8', '\xf6'),
+ ('\xf8', '\u01ba'), ('\u01bb', '\u01bb'), ('\u01bc', '\u01bf'), ('\u01c0', '\u01c3'),
+ ('\u01c4', '\u0293'), ('\u0294', '\u0294'), ('\u0295', '\u02af'), ('\u02b0', '\u02c1'),
+ ('\u02c6', '\u02d1'), ('\u02e0', '\u02e4'), ('\u02ec', '\u02ec'), ('\u02ee', '\u02ee'),
+ ('\u0300', '\u036f'), ('\u0370', '\u0373'), ('\u0374', '\u0374'), ('\u0376', '\u0377'),
+ ('\u037b', '\u037d'), ('\u037f', '\u037f'), ('\u0386', '\u0386'), ('\u0387', '\u0387'),
+ ('\u0388', '\u038a'), ('\u038c', '\u038c'), ('\u038e', '\u03a1'), ('\u03a3', '\u03f5'),
+ ('\u03f7', '\u0481'), ('\u0483', '\u0487'), ('\u048a', '\u052f'), ('\u0531', '\u0556'),
+ ('\u0559', '\u0559'), ('\u0561', '\u0587'), ('\u0591', '\u05bd'), ('\u05bf', '\u05bf'),
+ ('\u05c1', '\u05c2'), ('\u05c4', '\u05c5'), ('\u05c7', '\u05c7'), ('\u05d0', '\u05ea'),
+ ('\u05f0', '\u05f2'), ('\u0610', '\u061a'), ('\u0620', '\u063f'), ('\u0640', '\u0640'),
+ ('\u0641', '\u064a'), ('\u064b', '\u065f'), ('\u0660', '\u0669'), ('\u066e', '\u066f'),
+ ('\u0670', '\u0670'), ('\u0671', '\u06d3'), ('\u06d5', '\u06d5'), ('\u06d6', '\u06dc'),
+ ('\u06df', '\u06e4'), ('\u06e5', '\u06e6'), ('\u06e7', '\u06e8'), ('\u06ea', '\u06ed'),
+ ('\u06ee', '\u06ef'), ('\u06f0', '\u06f9'), ('\u06fa', '\u06fc'), ('\u06ff', '\u06ff'),
+ ('\u0710', '\u0710'), ('\u0711', '\u0711'), ('\u0712', '\u072f'), ('\u0730', '\u074a'),
+ ('\u074d', '\u07a5'), ('\u07a6', '\u07b0'), ('\u07b1', '\u07b1'), ('\u07c0', '\u07c9'),
+ ('\u07ca', '\u07ea'), ('\u07eb', '\u07f3'), ('\u07f4', '\u07f5'), ('\u07fa', '\u07fa'),
+ ('\u0800', '\u0815'), ('\u0816', '\u0819'), ('\u081a', '\u081a'), ('\u081b', '\u0823'),
+ ('\u0824', '\u0824'), ('\u0825', '\u0827'), ('\u0828', '\u0828'), ('\u0829', '\u082d'),
+ ('\u0840', '\u0858'), ('\u0859', '\u085b'), ('\u08a0', '\u08b2'), ('\u08e4', '\u0902'),
+ ('\u0903', '\u0903'), ('\u0904', '\u0939'), ('\u093a', '\u093a'), ('\u093b', '\u093b'),
+ ('\u093c', '\u093c'), ('\u093d', '\u093d'), ('\u093e', '\u0940'), ('\u0941', '\u0948'),
+ ('\u0949', '\u094c'), ('\u094d', '\u094d'), ('\u094e', '\u094f'), ('\u0950', '\u0950'),
+ ('\u0951', '\u0957'), ('\u0958', '\u0961'), ('\u0962', '\u0963'), ('\u0966', '\u096f'),
+ ('\u0971', '\u0971'), ('\u0972', '\u0980'), ('\u0981', '\u0981'), ('\u0982', '\u0983'),
+ ('\u0985', '\u098c'), ('\u098f', '\u0990'), ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'),
+ ('\u09b2', '\u09b2'), ('\u09b6', '\u09b9'), ('\u09bc', '\u09bc'), ('\u09bd', '\u09bd'),
+ ('\u09be', '\u09c0'), ('\u09c1', '\u09c4'), ('\u09c7', '\u09c8'), ('\u09cb', '\u09cc'),
+ ('\u09cd', '\u09cd'), ('\u09ce', '\u09ce'), ('\u09d7', '\u09d7'), ('\u09dc', '\u09dd'),
+ ('\u09df', '\u09e1'), ('\u09e2', '\u09e3'), ('\u09e6', '\u09ef'), ('\u09f0', '\u09f1'),
+ ('\u0a01', '\u0a02'), ('\u0a03', '\u0a03'), ('\u0a05', '\u0a0a'), ('\u0a0f', '\u0a10'),
+ ('\u0a13', '\u0a28'), ('\u0a2a', '\u0a30'), ('\u0a32', '\u0a33'), ('\u0a35', '\u0a36'),
+ ('\u0a38', '\u0a39'), ('\u0a3c', '\u0a3c'), ('\u0a3e', '\u0a40'), ('\u0a41', '\u0a42'),
+ ('\u0a47', '\u0a48'), ('\u0a4b', '\u0a4d'), ('\u0a51', '\u0a51'), ('\u0a59', '\u0a5c'),
+ ('\u0a5e', '\u0a5e'), ('\u0a66', '\u0a6f'), ('\u0a70', '\u0a71'), ('\u0a72', '\u0a74'),
+ ('\u0a75', '\u0a75'), ('\u0a81', '\u0a82'), ('\u0a83', '\u0a83'), ('\u0a85', '\u0a8d'),
+ ('\u0a8f', '\u0a91'), ('\u0a93', '\u0aa8'), ('\u0aaa', '\u0ab0'), ('\u0ab2', '\u0ab3'),
+ ('\u0ab5', '\u0ab9'), ('\u0abc', '\u0abc'), ('\u0abd', '\u0abd'), ('\u0abe', '\u0ac0'),
+ ('\u0ac1', '\u0ac5'), ('\u0ac7', '\u0ac8'), ('\u0ac9', '\u0ac9'), ('\u0acb', '\u0acc'),
+ ('\u0acd', '\u0acd'), ('\u0ad0', '\u0ad0'), ('\u0ae0', '\u0ae1'), ('\u0ae2', '\u0ae3'),
+ ('\u0ae6', '\u0aef'), ('\u0b01', '\u0b01'), ('\u0b02', '\u0b03'), ('\u0b05', '\u0b0c'),
+ ('\u0b0f', '\u0b10'), ('\u0b13', '\u0b28'), ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'),
+ ('\u0b35', '\u0b39'), ('\u0b3c', '\u0b3c'), ('\u0b3d', '\u0b3d'), ('\u0b3e', '\u0b3e'),
+ ('\u0b3f', '\u0b3f'), ('\u0b40', '\u0b40'), ('\u0b41', '\u0b44'), ('\u0b47', '\u0b48'),
+ ('\u0b4b', '\u0b4c'), ('\u0b4d', '\u0b4d'), ('\u0b56', '\u0b56'), ('\u0b57', '\u0b57'),
+ ('\u0b5c', '\u0b5d'), ('\u0b5f', '\u0b61'), ('\u0b62', '\u0b63'), ('\u0b66', '\u0b6f'),
+ ('\u0b71', '\u0b71'), ('\u0b82', '\u0b82'), ('\u0b83', '\u0b83'), ('\u0b85', '\u0b8a'),
+ ('\u0b8e', '\u0b90'), ('\u0b92', '\u0b95'), ('\u0b99', '\u0b9a'), ('\u0b9c', '\u0b9c'),
+ ('\u0b9e', '\u0b9f'), ('\u0ba3', '\u0ba4'), ('\u0ba8', '\u0baa'), ('\u0bae', '\u0bb9'),
+ ('\u0bbe', '\u0bbf'), ('\u0bc0', '\u0bc0'), ('\u0bc1', '\u0bc2'), ('\u0bc6', '\u0bc8'),
+ ('\u0bca', '\u0bcc'), ('\u0bcd', '\u0bcd'), ('\u0bd0', '\u0bd0'), ('\u0bd7', '\u0bd7'),
+ ('\u0be6', '\u0bef'), ('\u0c00', '\u0c00'), ('\u0c01', '\u0c03'), ('\u0c05', '\u0c0c'),
+ ('\u0c0e', '\u0c10'), ('\u0c12', '\u0c28'), ('\u0c2a', '\u0c39'), ('\u0c3d', '\u0c3d'),
+ ('\u0c3e', '\u0c40'), ('\u0c41', '\u0c44'), ('\u0c46', '\u0c48'), ('\u0c4a', '\u0c4d'),
+ ('\u0c55', '\u0c56'), ('\u0c58', '\u0c59'), ('\u0c60', '\u0c61'), ('\u0c62', '\u0c63'),
+ ('\u0c66', '\u0c6f'), ('\u0c81', '\u0c81'), ('\u0c82', '\u0c83'), ('\u0c85', '\u0c8c'),
+ ('\u0c8e', '\u0c90'), ('\u0c92', '\u0ca8'), ('\u0caa', '\u0cb3'), ('\u0cb5', '\u0cb9'),
+ ('\u0cbc', '\u0cbc'), ('\u0cbd', '\u0cbd'), ('\u0cbe', '\u0cbe'), ('\u0cbf', '\u0cbf'),
+ ('\u0cc0', '\u0cc4'), ('\u0cc6', '\u0cc6'), ('\u0cc7', '\u0cc8'), ('\u0cca', '\u0ccb'),
+ ('\u0ccc', '\u0ccd'), ('\u0cd5', '\u0cd6'), ('\u0cde', '\u0cde'), ('\u0ce0', '\u0ce1'),
+ ('\u0ce2', '\u0ce3'), ('\u0ce6', '\u0cef'), ('\u0cf1', '\u0cf2'), ('\u0d01', '\u0d01'),
+ ('\u0d02', '\u0d03'), ('\u0d05', '\u0d0c'), ('\u0d0e', '\u0d10'), ('\u0d12', '\u0d3a'),
+ ('\u0d3d', '\u0d3d'), ('\u0d3e', '\u0d40'), ('\u0d41', '\u0d44'), ('\u0d46', '\u0d48'),
+ ('\u0d4a', '\u0d4c'), ('\u0d4d', '\u0d4d'), ('\u0d4e', '\u0d4e'), ('\u0d57', '\u0d57'),
+ ('\u0d60', '\u0d61'), ('\u0d62', '\u0d63'), ('\u0d66', '\u0d6f'), ('\u0d7a', '\u0d7f'),
+ ('\u0d82', '\u0d83'), ('\u0d85', '\u0d96'), ('\u0d9a', '\u0db1'), ('\u0db3', '\u0dbb'),
+ ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'), ('\u0dca', '\u0dca'), ('\u0dcf', '\u0dd1'),
+ ('\u0dd2', '\u0dd4'), ('\u0dd6', '\u0dd6'), ('\u0dd8', '\u0ddf'), ('\u0de6', '\u0def'),
+ ('\u0df2', '\u0df3'), ('\u0e01', '\u0e30'), ('\u0e31', '\u0e31'), ('\u0e32', '\u0e33'),
+ ('\u0e34', '\u0e3a'), ('\u0e40', '\u0e45'), ('\u0e46', '\u0e46'), ('\u0e47', '\u0e4e'),
+ ('\u0e50', '\u0e59'), ('\u0e81', '\u0e82'), ('\u0e84', '\u0e84'), ('\u0e87', '\u0e88'),
+ ('\u0e8a', '\u0e8a'), ('\u0e8d', '\u0e8d'), ('\u0e94', '\u0e97'), ('\u0e99', '\u0e9f'),
+ ('\u0ea1', '\u0ea3'), ('\u0ea5', '\u0ea5'), ('\u0ea7', '\u0ea7'), ('\u0eaa', '\u0eab'),
+ ('\u0ead', '\u0eb0'), ('\u0eb1', '\u0eb1'), ('\u0eb2', '\u0eb3'), ('\u0eb4', '\u0eb9'),
+ ('\u0ebb', '\u0ebc'), ('\u0ebd', '\u0ebd'), ('\u0ec0', '\u0ec4'), ('\u0ec6', '\u0ec6'),
+ ('\u0ec8', '\u0ecd'), ('\u0ed0', '\u0ed9'), ('\u0edc', '\u0edf'), ('\u0f00', '\u0f00'),
+ ('\u0f18', '\u0f19'), ('\u0f20', '\u0f29'), ('\u0f35', '\u0f35'), ('\u0f37', '\u0f37'),
+ ('\u0f39', '\u0f39'), ('\u0f3e', '\u0f3f'), ('\u0f40', '\u0f47'), ('\u0f49', '\u0f6c'),
+ ('\u0f71', '\u0f7e'), ('\u0f7f', '\u0f7f'), ('\u0f80', '\u0f84'), ('\u0f86', '\u0f87'),
+ ('\u0f88', '\u0f8c'), ('\u0f8d', '\u0f97'), ('\u0f99', '\u0fbc'), ('\u0fc6', '\u0fc6'),
+ ('\u1000', '\u102a'), ('\u102b', '\u102c'), ('\u102d', '\u1030'), ('\u1031', '\u1031'),
+ ('\u1032', '\u1037'), ('\u1038', '\u1038'), ('\u1039', '\u103a'), ('\u103b', '\u103c'),
+ ('\u103d', '\u103e'), ('\u103f', '\u103f'), ('\u1040', '\u1049'), ('\u1050', '\u1055'),
+ ('\u1056', '\u1057'), ('\u1058', '\u1059'), ('\u105a', '\u105d'), ('\u105e', '\u1060'),
+ ('\u1061', '\u1061'), ('\u1062', '\u1064'), ('\u1065', '\u1066'), ('\u1067', '\u106d'),
+ ('\u106e', '\u1070'), ('\u1071', '\u1074'), ('\u1075', '\u1081'), ('\u1082', '\u1082'),
+ ('\u1083', '\u1084'), ('\u1085', '\u1086'), ('\u1087', '\u108c'), ('\u108d', '\u108d'),
+ ('\u108e', '\u108e'), ('\u108f', '\u108f'), ('\u1090', '\u1099'), ('\u109a', '\u109c'),
+ ('\u109d', '\u109d'), ('\u10a0', '\u10c5'), ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'),
+ ('\u10d0', '\u10fa'), ('\u10fc', '\u10fc'), ('\u10fd', '\u1248'), ('\u124a', '\u124d'),
+ ('\u1250', '\u1256'), ('\u1258', '\u1258'), ('\u125a', '\u125d'), ('\u1260', '\u1288'),
+ ('\u128a', '\u128d'), ('\u1290', '\u12b0'), ('\u12b2', '\u12b5'), ('\u12b8', '\u12be'),
+ ('\u12c0', '\u12c0'), ('\u12c2', '\u12c5'), ('\u12c8', '\u12d6'), ('\u12d8', '\u1310'),
+ ('\u1312', '\u1315'), ('\u1318', '\u135a'), ('\u135d', '\u135f'), ('\u1369', '\u1371'),
+ ('\u1380', '\u138f'), ('\u13a0', '\u13f4'), ('\u1401', '\u166c'), ('\u166f', '\u167f'),
+ ('\u1681', '\u169a'), ('\u16a0', '\u16ea'), ('\u16ee', '\u16f0'), ('\u16f1', '\u16f8'),
+ ('\u1700', '\u170c'), ('\u170e', '\u1711'), ('\u1712', '\u1714'), ('\u1720', '\u1731'),
+ ('\u1732', '\u1734'), ('\u1740', '\u1751'), ('\u1752', '\u1753'), ('\u1760', '\u176c'),
+ ('\u176e', '\u1770'), ('\u1772', '\u1773'), ('\u1780', '\u17b3'), ('\u17b4', '\u17b5'),
+ ('\u17b6', '\u17b6'), ('\u17b7', '\u17bd'), ('\u17be', '\u17c5'), ('\u17c6', '\u17c6'),
+ ('\u17c7', '\u17c8'), ('\u17c9', '\u17d3'), ('\u17d7', '\u17d7'), ('\u17dc', '\u17dc'),
+ ('\u17dd', '\u17dd'), ('\u17e0', '\u17e9'), ('\u180b', '\u180d'), ('\u1810', '\u1819'),
+ ('\u1820', '\u1842'), ('\u1843', '\u1843'), ('\u1844', '\u1877'), ('\u1880', '\u18a8'),
+ ('\u18a9', '\u18a9'), ('\u18aa', '\u18aa'), ('\u18b0', '\u18f5'), ('\u1900', '\u191e'),
+ ('\u1920', '\u1922'), ('\u1923', '\u1926'), ('\u1927', '\u1928'), ('\u1929', '\u192b'),
+ ('\u1930', '\u1931'), ('\u1932', '\u1932'), ('\u1933', '\u1938'), ('\u1939', '\u193b'),
+ ('\u1946', '\u194f'), ('\u1950', '\u196d'), ('\u1970', '\u1974'), ('\u1980', '\u19ab'),
+ ('\u19b0', '\u19c0'), ('\u19c1', '\u19c7'), ('\u19c8', '\u19c9'), ('\u19d0', '\u19d9'),
+ ('\u19da', '\u19da'), ('\u1a00', '\u1a16'), ('\u1a17', '\u1a18'), ('\u1a19', '\u1a1a'),
+ ('\u1a1b', '\u1a1b'), ('\u1a20', '\u1a54'), ('\u1a55', '\u1a55'), ('\u1a56', '\u1a56'),
+ ('\u1a57', '\u1a57'), ('\u1a58', '\u1a5e'), ('\u1a60', '\u1a60'), ('\u1a61', '\u1a61'),
+ ('\u1a62', '\u1a62'), ('\u1a63', '\u1a64'), ('\u1a65', '\u1a6c'), ('\u1a6d', '\u1a72'),
+ ('\u1a73', '\u1a7c'), ('\u1a7f', '\u1a7f'), ('\u1a80', '\u1a89'), ('\u1a90', '\u1a99'),
+ ('\u1aa7', '\u1aa7'), ('\u1ab0', '\u1abd'), ('\u1b00', '\u1b03'), ('\u1b04', '\u1b04'),
+ ('\u1b05', '\u1b33'), ('\u1b34', '\u1b34'), ('\u1b35', '\u1b35'), ('\u1b36', '\u1b3a'),
+ ('\u1b3b', '\u1b3b'), ('\u1b3c', '\u1b3c'), ('\u1b3d', '\u1b41'), ('\u1b42', '\u1b42'),
+ ('\u1b43', '\u1b44'), ('\u1b45', '\u1b4b'), ('\u1b50', '\u1b59'), ('\u1b6b', '\u1b73'),
+ ('\u1b80', '\u1b81'), ('\u1b82', '\u1b82'), ('\u1b83', '\u1ba0'), ('\u1ba1', '\u1ba1'),
+ ('\u1ba2', '\u1ba5'), ('\u1ba6', '\u1ba7'), ('\u1ba8', '\u1ba9'), ('\u1baa', '\u1baa'),
+ ('\u1bab', '\u1bad'), ('\u1bae', '\u1baf'), ('\u1bb0', '\u1bb9'), ('\u1bba', '\u1be5'),
+ ('\u1be6', '\u1be6'), ('\u1be7', '\u1be7'), ('\u1be8', '\u1be9'), ('\u1bea', '\u1bec'),
+ ('\u1bed', '\u1bed'), ('\u1bee', '\u1bee'), ('\u1bef', '\u1bf1'), ('\u1bf2', '\u1bf3'),
+ ('\u1c00', '\u1c23'), ('\u1c24', '\u1c2b'), ('\u1c2c', '\u1c33'), ('\u1c34', '\u1c35'),
+ ('\u1c36', '\u1c37'), ('\u1c40', '\u1c49'), ('\u1c4d', '\u1c4f'), ('\u1c50', '\u1c59'),
+ ('\u1c5a', '\u1c77'), ('\u1c78', '\u1c7d'), ('\u1cd0', '\u1cd2'), ('\u1cd4', '\u1ce0'),
+ ('\u1ce1', '\u1ce1'), ('\u1ce2', '\u1ce8'), ('\u1ce9', '\u1cec'), ('\u1ced', '\u1ced'),
+ ('\u1cee', '\u1cf1'), ('\u1cf2', '\u1cf3'), ('\u1cf4', '\u1cf4'), ('\u1cf5', '\u1cf6'),
+ ('\u1cf8', '\u1cf9'), ('\u1d00', '\u1d2b'), ('\u1d2c', '\u1d6a'), ('\u1d6b', '\u1d77'),
+ ('\u1d78', '\u1d78'), ('\u1d79', '\u1d9a'), ('\u1d9b', '\u1dbf'), ('\u1dc0', '\u1df5'),
+ ('\u1dfc', '\u1dff'), ('\u1e00', '\u1f15'), ('\u1f18', '\u1f1d'), ('\u1f20', '\u1f45'),
+ ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'), ('\u1f59', '\u1f59'), ('\u1f5b', '\u1f5b'),
+ ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'), ('\u1f80', '\u1fb4'), ('\u1fb6', '\u1fbc'),
+ ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fcc'), ('\u1fd0', '\u1fd3'),
+ ('\u1fd6', '\u1fdb'), ('\u1fe0', '\u1fec'), ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ffc'),
+ ('\u203f', '\u2040'), ('\u2054', '\u2054'), ('\u2071', '\u2071'), ('\u207f', '\u207f'),
+ ('\u2090', '\u209c'), ('\u20d0', '\u20dc'), ('\u20e1', '\u20e1'), ('\u20e5', '\u20f0'),
+ ('\u2102', '\u2102'), ('\u2107', '\u2107'), ('\u210a', '\u2113'), ('\u2115', '\u2115'),
+ ('\u2118', '\u2118'), ('\u2119', '\u211d'), ('\u2124', '\u2124'), ('\u2126', '\u2126'),
+ ('\u2128', '\u2128'), ('\u212a', '\u212d'), ('\u212e', '\u212e'), ('\u212f', '\u2134'),
+ ('\u2135', '\u2138'), ('\u2139', '\u2139'), ('\u213c', '\u213f'), ('\u2145', '\u2149'),
+ ('\u214e', '\u214e'), ('\u2160', '\u2182'), ('\u2183', '\u2184'), ('\u2185', '\u2188'),
+ ('\u2c00', '\u2c2e'), ('\u2c30', '\u2c5e'), ('\u2c60', '\u2c7b'), ('\u2c7c', '\u2c7d'),
+ ('\u2c7e', '\u2ce4'), ('\u2ceb', '\u2cee'), ('\u2cef', '\u2cf1'), ('\u2cf2', '\u2cf3'),
+ ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'), ('\u2d30', '\u2d67'),
+ ('\u2d6f', '\u2d6f'), ('\u2d7f', '\u2d7f'), ('\u2d80', '\u2d96'), ('\u2da0', '\u2da6'),
+ ('\u2da8', '\u2dae'), ('\u2db0', '\u2db6'), ('\u2db8', '\u2dbe'), ('\u2dc0', '\u2dc6'),
+ ('\u2dc8', '\u2dce'), ('\u2dd0', '\u2dd6'), ('\u2dd8', '\u2dde'), ('\u2de0', '\u2dff'),
+ ('\u3005', '\u3005'), ('\u3006', '\u3006'), ('\u3007', '\u3007'), ('\u3021', '\u3029'),
+ ('\u302a', '\u302d'), ('\u302e', '\u302f'), ('\u3031', '\u3035'), ('\u3038', '\u303a'),
+ ('\u303b', '\u303b'), ('\u303c', '\u303c'), ('\u3041', '\u3096'), ('\u3099', '\u309a'),
+ ('\u309d', '\u309e'), ('\u309f', '\u309f'), ('\u30a1', '\u30fa'), ('\u30fc', '\u30fe'),
+ ('\u30ff', '\u30ff'), ('\u3105', '\u312d'), ('\u3131', '\u318e'), ('\u31a0', '\u31ba'),
+ ('\u31f0', '\u31ff'), ('\u3400', '\u4db5'), ('\u4e00', '\u9fcc'), ('\ua000', '\ua014'),
+ ('\ua015', '\ua015'), ('\ua016', '\ua48c'), ('\ua4d0', '\ua4f7'), ('\ua4f8', '\ua4fd'),
+ ('\ua500', '\ua60b'), ('\ua60c', '\ua60c'), ('\ua610', '\ua61f'), ('\ua620', '\ua629'),
+ ('\ua62a', '\ua62b'), ('\ua640', '\ua66d'), ('\ua66e', '\ua66e'), ('\ua66f', '\ua66f'),
+ ('\ua674', '\ua67d'), ('\ua67f', '\ua67f'), ('\ua680', '\ua69b'), ('\ua69c', '\ua69d'),
+ ('\ua69f', '\ua69f'), ('\ua6a0', '\ua6e5'), ('\ua6e6', '\ua6ef'), ('\ua6f0', '\ua6f1'),
+ ('\ua717', '\ua71f'), ('\ua722', '\ua76f'), ('\ua770', '\ua770'), ('\ua771', '\ua787'),
+ ('\ua788', '\ua788'), ('\ua78b', '\ua78e'), ('\ua790', '\ua7ad'), ('\ua7b0', '\ua7b1'),
+ ('\ua7f7', '\ua7f7'), ('\ua7f8', '\ua7f9'), ('\ua7fa', '\ua7fa'), ('\ua7fb', '\ua801'),
+ ('\ua802', '\ua802'), ('\ua803', '\ua805'), ('\ua806', '\ua806'), ('\ua807', '\ua80a'),
+ ('\ua80b', '\ua80b'), ('\ua80c', '\ua822'), ('\ua823', '\ua824'), ('\ua825', '\ua826'),
+ ('\ua827', '\ua827'), ('\ua840', '\ua873'), ('\ua880', '\ua881'), ('\ua882', '\ua8b3'),
+ ('\ua8b4', '\ua8c3'), ('\ua8c4', '\ua8c4'), ('\ua8d0', '\ua8d9'), ('\ua8e0', '\ua8f1'),
+ ('\ua8f2', '\ua8f7'), ('\ua8fb', '\ua8fb'), ('\ua900', '\ua909'), ('\ua90a', '\ua925'),
+ ('\ua926', '\ua92d'), ('\ua930', '\ua946'), ('\ua947', '\ua951'), ('\ua952', '\ua953'),
+ ('\ua960', '\ua97c'), ('\ua980', '\ua982'), ('\ua983', '\ua983'), ('\ua984', '\ua9b2'),
+ ('\ua9b3', '\ua9b3'), ('\ua9b4', '\ua9b5'), ('\ua9b6', '\ua9b9'), ('\ua9ba', '\ua9bb'),
+ ('\ua9bc', '\ua9bc'), ('\ua9bd', '\ua9c0'), ('\ua9cf', '\ua9cf'), ('\ua9d0', '\ua9d9'),
+ ('\ua9e0', '\ua9e4'), ('\ua9e5', '\ua9e5'), ('\ua9e6', '\ua9e6'), ('\ua9e7', '\ua9ef'),
+ ('\ua9f0', '\ua9f9'), ('\ua9fa', '\ua9fe'), ('\uaa00', '\uaa28'), ('\uaa29', '\uaa2e'),
+ ('\uaa2f', '\uaa30'), ('\uaa31', '\uaa32'), ('\uaa33', '\uaa34'), ('\uaa35', '\uaa36'),
+ ('\uaa40', '\uaa42'), ('\uaa43', '\uaa43'), ('\uaa44', '\uaa4b'), ('\uaa4c', '\uaa4c'),
+ ('\uaa4d', '\uaa4d'), ('\uaa50', '\uaa59'), ('\uaa60', '\uaa6f'), ('\uaa70', '\uaa70'),
+ ('\uaa71', '\uaa76'), ('\uaa7a', '\uaa7a'), ('\uaa7b', '\uaa7b'), ('\uaa7c', '\uaa7c'),
+ ('\uaa7d', '\uaa7d'), ('\uaa7e', '\uaaaf'), ('\uaab0', '\uaab0'), ('\uaab1', '\uaab1'),
+ ('\uaab2', '\uaab4'), ('\uaab5', '\uaab6'), ('\uaab7', '\uaab8'), ('\uaab9', '\uaabd'),
+ ('\uaabe', '\uaabf'), ('\uaac0', '\uaac0'), ('\uaac1', '\uaac1'), ('\uaac2', '\uaac2'),
+ ('\uaadb', '\uaadc'), ('\uaadd', '\uaadd'), ('\uaae0', '\uaaea'), ('\uaaeb', '\uaaeb'),
+ ('\uaaec', '\uaaed'), ('\uaaee', '\uaaef'), ('\uaaf2', '\uaaf2'), ('\uaaf3', '\uaaf4'),
+ ('\uaaf5', '\uaaf5'), ('\uaaf6', '\uaaf6'), ('\uab01', '\uab06'), ('\uab09', '\uab0e'),
+ ('\uab11', '\uab16'), ('\uab20', '\uab26'), ('\uab28', '\uab2e'), ('\uab30', '\uab5a'),
+ ('\uab5c', '\uab5f'), ('\uab64', '\uab65'), ('\uabc0', '\uabe2'), ('\uabe3', '\uabe4'),
+ ('\uabe5', '\uabe5'), ('\uabe6', '\uabe7'), ('\uabe8', '\uabe8'), ('\uabe9', '\uabea'),
+ ('\uabec', '\uabec'), ('\uabed', '\uabed'), ('\uabf0', '\uabf9'), ('\uac00', '\ud7a3'),
+ ('\ud7b0', '\ud7c6'), ('\ud7cb', '\ud7fb'), ('\uf900', '\ufa6d'), ('\ufa70', '\ufad9'),
+ ('\ufb00', '\ufb06'), ('\ufb13', '\ufb17'), ('\ufb1d', '\ufb1d'), ('\ufb1e', '\ufb1e'),
+ ('\ufb1f', '\ufb28'), ('\ufb2a', '\ufb36'), ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'),
+ ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'), ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufc5d'),
+ ('\ufc64', '\ufd3d'), ('\ufd50', '\ufd8f'), ('\ufd92', '\ufdc7'), ('\ufdf0', '\ufdf9'),
+ ('\ufe00', '\ufe0f'), ('\ufe20', '\ufe2d'), ('\ufe33', '\ufe34'), ('\ufe4d', '\ufe4f'),
+ ('\ufe71', '\ufe71'), ('\ufe73', '\ufe73'), ('\ufe77', '\ufe77'), ('\ufe79', '\ufe79'),
+ ('\ufe7b', '\ufe7b'), ('\ufe7d', '\ufe7d'), ('\ufe7f', '\ufefc'), ('\uff10', '\uff19'),
+ ('\uff21', '\uff3a'), ('\uff3f', '\uff3f'), ('\uff41', '\uff5a'), ('\uff66', '\uff6f'),
+ ('\uff70', '\uff70'), ('\uff71', '\uff9d'), ('\uff9e', '\uff9f'), ('\uffa0', '\uffbe'),
+ ('\uffc2', '\uffc7'), ('\uffca', '\uffcf'), ('\uffd2', '\uffd7'), ('\uffda', '\uffdc'),
+ ('\U00010000', '\U0001000b'), ('\U0001000d', '\U00010026'), ('\U00010028', '\U0001003a'),
+ ('\U0001003c', '\U0001003d'), ('\U0001003f', '\U0001004d'), ('\U00010050', '\U0001005d'),
+ ('\U00010080', '\U000100fa'), ('\U00010140', '\U00010174'), ('\U000101fd', '\U000101fd'),
+ ('\U00010280', '\U0001029c'), ('\U000102a0', '\U000102d0'), ('\U000102e0', '\U000102e0'),
+ ('\U00010300', '\U0001031f'), ('\U00010330', '\U00010340'), ('\U00010341', '\U00010341'),
+ ('\U00010342', '\U00010349'), ('\U0001034a', '\U0001034a'), ('\U00010350', '\U00010375'),
+ ('\U00010376', '\U0001037a'), ('\U00010380', '\U0001039d'), ('\U000103a0', '\U000103c3'),
+ ('\U000103c8', '\U000103cf'), ('\U000103d1', '\U000103d5'), ('\U00010400', '\U0001044f'),
+ ('\U00010450', '\U0001049d'), ('\U000104a0', '\U000104a9'), ('\U00010500', '\U00010527'),
+ ('\U00010530', '\U00010563'), ('\U00010600', '\U00010736'), ('\U00010740', '\U00010755'),
+ ('\U00010760', '\U00010767'), ('\U00010800', '\U00010805'), ('\U00010808', '\U00010808'),
+ ('\U0001080a', '\U00010835'), ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'),
+ ('\U0001083f', '\U00010855'), ('\U00010860', '\U00010876'), ('\U00010880', '\U0001089e'),
+ ('\U00010900', '\U00010915'), ('\U00010920', '\U00010939'), ('\U00010980', '\U000109b7'),
+ ('\U000109be', '\U000109bf'), ('\U00010a00', '\U00010a00'), ('\U00010a01', '\U00010a03'),
+ ('\U00010a05', '\U00010a06'), ('\U00010a0c', '\U00010a0f'), ('\U00010a10', '\U00010a13'),
+ ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'), ('\U00010a38', '\U00010a3a'),
+ ('\U00010a3f', '\U00010a3f'), ('\U00010a60', '\U00010a7c'), ('\U00010a80', '\U00010a9c'),
+ ('\U00010ac0', '\U00010ac7'), ('\U00010ac9', '\U00010ae4'), ('\U00010ae5', '\U00010ae6'),
+ ('\U00010b00', '\U00010b35'), ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'),
+ ('\U00010b80', '\U00010b91'), ('\U00010c00', '\U00010c48'), ('\U00011000', '\U00011000'),
+ ('\U00011001', '\U00011001'), ('\U00011002', '\U00011002'), ('\U00011003', '\U00011037'),
+ ('\U00011038', '\U00011046'), ('\U00011066', '\U0001106f'), ('\U0001107f', '\U00011081'),
+ ('\U00011082', '\U00011082'), ('\U00011083', '\U000110af'), ('\U000110b0', '\U000110b2'),
+ ('\U000110b3', '\U000110b6'), ('\U000110b7', '\U000110b8'), ('\U000110b9', '\U000110ba'),
+ ('\U000110d0', '\U000110e8'), ('\U000110f0', '\U000110f9'), ('\U00011100', '\U00011102'),
+ ('\U00011103', '\U00011126'), ('\U00011127', '\U0001112b'), ('\U0001112c', '\U0001112c'),
+ ('\U0001112d', '\U00011134'), ('\U00011136', '\U0001113f'), ('\U00011150', '\U00011172'),
+ ('\U00011173', '\U00011173'), ('\U00011176', '\U00011176'), ('\U00011180', '\U00011181'),
+ ('\U00011182', '\U00011182'), ('\U00011183', '\U000111b2'), ('\U000111b3', '\U000111b5'),
+ ('\U000111b6', '\U000111be'), ('\U000111bf', '\U000111c0'), ('\U000111c1', '\U000111c4'),
+ ('\U000111d0', '\U000111d9'), ('\U000111da', '\U000111da'), ('\U00011200', '\U00011211'),
+ ('\U00011213', '\U0001122b'), ('\U0001122c', '\U0001122e'), ('\U0001122f', '\U00011231'),
+ ('\U00011232', '\U00011233'), ('\U00011234', '\U00011234'), ('\U00011235', '\U00011235'),
+ ('\U00011236', '\U00011237'), ('\U000112b0', '\U000112de'), ('\U000112df', '\U000112df'),
+ ('\U000112e0', '\U000112e2'), ('\U000112e3', '\U000112ea'), ('\U000112f0', '\U000112f9'),
+ ('\U00011301', '\U00011301'), ('\U00011302', '\U00011303'), ('\U00011305', '\U0001130c'),
+ ('\U0001130f', '\U00011310'), ('\U00011313', '\U00011328'), ('\U0001132a', '\U00011330'),
+ ('\U00011332', '\U00011333'), ('\U00011335', '\U00011339'), ('\U0001133c', '\U0001133c'),
+ ('\U0001133d', '\U0001133d'), ('\U0001133e', '\U0001133f'), ('\U00011340', '\U00011340'),
+ ('\U00011341', '\U00011344'), ('\U00011347', '\U00011348'), ('\U0001134b', '\U0001134d'),
+ ('\U00011357', '\U00011357'), ('\U0001135d', '\U00011361'), ('\U00011362', '\U00011363'),
+ ('\U00011366', '\U0001136c'), ('\U00011370', '\U00011374'), ('\U00011480', '\U000114af'),
+ ('\U000114b0', '\U000114b2'), ('\U000114b3', '\U000114b8'), ('\U000114b9', '\U000114b9'),
+ ('\U000114ba', '\U000114ba'), ('\U000114bb', '\U000114be'), ('\U000114bf', '\U000114c0'),
+ ('\U000114c1', '\U000114c1'), ('\U000114c2', '\U000114c3'), ('\U000114c4', '\U000114c5'),
+ ('\U000114c7', '\U000114c7'), ('\U000114d0', '\U000114d9'), ('\U00011580', '\U000115ae'),
+ ('\U000115af', '\U000115b1'), ('\U000115b2', '\U000115b5'), ('\U000115b8', '\U000115bb'),
+ ('\U000115bc', '\U000115bd'), ('\U000115be', '\U000115be'), ('\U000115bf', '\U000115c0'),
+ ('\U00011600', '\U0001162f'), ('\U00011630', '\U00011632'), ('\U00011633', '\U0001163a'),
+ ('\U0001163b', '\U0001163c'), ('\U0001163d', '\U0001163d'), ('\U0001163e', '\U0001163e'),
+ ('\U0001163f', '\U00011640'), ('\U00011644', '\U00011644'), ('\U00011650', '\U00011659'),
+ ('\U00011680', '\U000116aa'), ('\U000116ab', '\U000116ab'), ('\U000116ac', '\U000116ac'),
+ ('\U000116ad', '\U000116ad'), ('\U000116ae', '\U000116af'), ('\U000116b0', '\U000116b5'),
+ ('\U000116b6', '\U000116b6'), ('\U000116b7', '\U000116b7'), ('\U000116c0', '\U000116c9'),
+ ('\U000118a0', '\U000118df'), ('\U000118e0', '\U000118e9'), ('\U000118ff', '\U000118ff'),
+ ('\U00011ac0', '\U00011af8'), ('\U00012000', '\U00012398'), ('\U00012400', '\U0001246e'),
+ ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'), ('\U00016a40', '\U00016a5e'),
+ ('\U00016a60', '\U00016a69'), ('\U00016ad0', '\U00016aed'), ('\U00016af0', '\U00016af4'),
+ ('\U00016b00', '\U00016b2f'), ('\U00016b30', '\U00016b36'), ('\U00016b40', '\U00016b43'),
+ ('\U00016b50', '\U00016b59'), ('\U00016b63', '\U00016b77'), ('\U00016b7d', '\U00016b8f'),
+ ('\U00016f00', '\U00016f44'), ('\U00016f50', '\U00016f50'), ('\U00016f51', '\U00016f7e'),
+ ('\U00016f8f', '\U00016f92'), ('\U00016f93', '\U00016f9f'), ('\U0001b000', '\U0001b001'),
+ ('\U0001bc00', '\U0001bc6a'), ('\U0001bc70', '\U0001bc7c'), ('\U0001bc80', '\U0001bc88'),
+ ('\U0001bc90', '\U0001bc99'), ('\U0001bc9d', '\U0001bc9e'), ('\U0001d165', '\U0001d166'),
+ ('\U0001d167', '\U0001d169'), ('\U0001d16d', '\U0001d172'), ('\U0001d17b', '\U0001d182'),
+ ('\U0001d185', '\U0001d18b'), ('\U0001d1aa', '\U0001d1ad'), ('\U0001d242', '\U0001d244'),
+ ('\U0001d400', '\U0001d454'), ('\U0001d456', '\U0001d49c'), ('\U0001d49e', '\U0001d49f'),
+ ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5', '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'),
+ ('\U0001d4ae', '\U0001d4b9'), ('\U0001d4bb', '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'),
+ ('\U0001d4c5', '\U0001d505'), ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'),
+ ('\U0001d516', '\U0001d51c'), ('\U0001d51e', '\U0001d539'), ('\U0001d53b', '\U0001d53e'),
+ ('\U0001d540', '\U0001d544'), ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'),
+ ('\U0001d552', '\U0001d6a5'), ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6c2', '\U0001d6da'),
+ ('\U0001d6dc', '\U0001d6fa'), ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d734'),
+ ('\U0001d736', '\U0001d74e'), ('\U0001d750', '\U0001d76e'), ('\U0001d770', '\U0001d788'),
+ ('\U0001d78a', '\U0001d7a8'), ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb'),
+ ('\U0001d7ce', '\U0001d7ff'), ('\U0001e800', '\U0001e8c4'), ('\U0001e8d0', '\U0001e8d6'),
+ ('\U0001ee00', '\U0001ee03'), ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'),
+ ('\U0001ee24', '\U0001ee24'), ('\U0001ee27', '\U0001ee27'), ('\U0001ee29', '\U0001ee32'),
+ ('\U0001ee34', '\U0001ee37'), ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'),
+ ('\U0001ee42', '\U0001ee42'), ('\U0001ee47', '\U0001ee47'), ('\U0001ee49', '\U0001ee49'),
+ ('\U0001ee4b', '\U0001ee4b'), ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'),
+ ('\U0001ee54', '\U0001ee54'), ('\U0001ee57', '\U0001ee57'), ('\U0001ee59', '\U0001ee59'),
+ ('\U0001ee5b', '\U0001ee5b'), ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'),
+ ('\U0001ee61', '\U0001ee62'), ('\U0001ee64', '\U0001ee64'), ('\U0001ee67', '\U0001ee6a'),
+ ('\U0001ee6c', '\U0001ee72'), ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'),
+ ('\U0001ee7e', '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'), ('\U0001ee8b', '\U0001ee9b'),
+ ('\U0001eea1', '\U0001eea3'), ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'),
+ ('\U00020000', '\U0002a6d6'), ('\U0002a700', '\U0002b734'), ('\U0002b740', '\U0002b81d'),
+ ('\U0002f800', '\U0002fa1d'), ('\U000e0100', '\U000e01ef')
+ ];
+
+ pub fn XID_Continue(c: char) -> bool {
+ super::bsearch_range_table(c, XID_Continue_table)
+ }
+
+ pub static XID_Start_table: &'static [(char, char)] = &[
+ ('\x41', '\x5a'), ('\x61', '\x7a'), ('\xaa', '\xaa'), ('\xb5', '\xb5'), ('\xba', '\xba'),
+ ('\xc0', '\xd6'), ('\xd8', '\xf6'), ('\xf8', '\u01ba'), ('\u01bb', '\u01bb'), ('\u01bc',
+ '\u01bf'), ('\u01c0', '\u01c3'), ('\u01c4', '\u0293'), ('\u0294', '\u0294'), ('\u0295',
+ '\u02af'), ('\u02b0', '\u02c1'), ('\u02c6', '\u02d1'), ('\u02e0', '\u02e4'), ('\u02ec',
+ '\u02ec'), ('\u02ee', '\u02ee'), ('\u0370', '\u0373'), ('\u0374', '\u0374'), ('\u0376',
+ '\u0377'), ('\u037b', '\u037d'), ('\u037f', '\u037f'), ('\u0386', '\u0386'), ('\u0388',
+ '\u038a'), ('\u038c', '\u038c'), ('\u038e', '\u03a1'), ('\u03a3', '\u03f5'), ('\u03f7',
+ '\u0481'), ('\u048a', '\u052f'), ('\u0531', '\u0556'), ('\u0559', '\u0559'), ('\u0561',
+ '\u0587'), ('\u05d0', '\u05ea'), ('\u05f0', '\u05f2'), ('\u0620', '\u063f'), ('\u0640',
+ '\u0640'), ('\u0641', '\u064a'), ('\u066e', '\u066f'), ('\u0671', '\u06d3'), ('\u06d5',
+ '\u06d5'), ('\u06e5', '\u06e6'), ('\u06ee', '\u06ef'), ('\u06fa', '\u06fc'), ('\u06ff',
+ '\u06ff'), ('\u0710', '\u0710'), ('\u0712', '\u072f'), ('\u074d', '\u07a5'), ('\u07b1',
+ '\u07b1'), ('\u07ca', '\u07ea'), ('\u07f4', '\u07f5'), ('\u07fa', '\u07fa'), ('\u0800',
+ '\u0815'), ('\u081a', '\u081a'), ('\u0824', '\u0824'), ('\u0828', '\u0828'), ('\u0840',
+ '\u0858'), ('\u08a0', '\u08b2'), ('\u0904', '\u0939'), ('\u093d', '\u093d'), ('\u0950',
+ '\u0950'), ('\u0958', '\u0961'), ('\u0971', '\u0971'), ('\u0972', '\u0980'), ('\u0985',
+ '\u098c'), ('\u098f', '\u0990'), ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'), ('\u09b2',
+ '\u09b2'), ('\u09b6', '\u09b9'), ('\u09bd', '\u09bd'), ('\u09ce', '\u09ce'), ('\u09dc',
+ '\u09dd'), ('\u09df', '\u09e1'), ('\u09f0', '\u09f1'), ('\u0a05', '\u0a0a'), ('\u0a0f',
+ '\u0a10'), ('\u0a13', '\u0a28'), ('\u0a2a', '\u0a30'), ('\u0a32', '\u0a33'), ('\u0a35',
+ '\u0a36'), ('\u0a38', '\u0a39'), ('\u0a59', '\u0a5c'), ('\u0a5e', '\u0a5e'), ('\u0a72',
+ '\u0a74'), ('\u0a85', '\u0a8d'), ('\u0a8f', '\u0a91'), ('\u0a93', '\u0aa8'), ('\u0aaa',
+ '\u0ab0'), ('\u0ab2', '\u0ab3'), ('\u0ab5', '\u0ab9'), ('\u0abd', '\u0abd'), ('\u0ad0',
+ '\u0ad0'), ('\u0ae0', '\u0ae1'), ('\u0b05', '\u0b0c'), ('\u0b0f', '\u0b10'), ('\u0b13',
+ '\u0b28'), ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'), ('\u0b35', '\u0b39'), ('\u0b3d',
+ '\u0b3d'), ('\u0b5c', '\u0b5d'), ('\u0b5f', '\u0b61'), ('\u0b71', '\u0b71'), ('\u0b83',
+ '\u0b83'), ('\u0b85', '\u0b8a'), ('\u0b8e', '\u0b90'), ('\u0b92', '\u0b95'), ('\u0b99',
+ '\u0b9a'), ('\u0b9c', '\u0b9c'), ('\u0b9e', '\u0b9f'), ('\u0ba3', '\u0ba4'), ('\u0ba8',
+ '\u0baa'), ('\u0bae', '\u0bb9'), ('\u0bd0', '\u0bd0'), ('\u0c05', '\u0c0c'), ('\u0c0e',
+ '\u0c10'), ('\u0c12', '\u0c28'), ('\u0c2a', '\u0c39'), ('\u0c3d', '\u0c3d'), ('\u0c58',
+ '\u0c59'), ('\u0c60', '\u0c61'), ('\u0c85', '\u0c8c'), ('\u0c8e', '\u0c90'), ('\u0c92',
+ '\u0ca8'), ('\u0caa', '\u0cb3'), ('\u0cb5', '\u0cb9'), ('\u0cbd', '\u0cbd'), ('\u0cde',
+ '\u0cde'), ('\u0ce0', '\u0ce1'), ('\u0cf1', '\u0cf2'), ('\u0d05', '\u0d0c'), ('\u0d0e',
+ '\u0d10'), ('\u0d12', '\u0d3a'), ('\u0d3d', '\u0d3d'), ('\u0d4e', '\u0d4e'), ('\u0d60',
+ '\u0d61'), ('\u0d7a', '\u0d7f'), ('\u0d85', '\u0d96'), ('\u0d9a', '\u0db1'), ('\u0db3',
+ '\u0dbb'), ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'), ('\u0e01', '\u0e30'), ('\u0e32',
+ '\u0e32'), ('\u0e40', '\u0e45'), ('\u0e46', '\u0e46'), ('\u0e81', '\u0e82'), ('\u0e84',
+ '\u0e84'), ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'), ('\u0e8d', '\u0e8d'), ('\u0e94',
+ '\u0e97'), ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'), ('\u0ea5', '\u0ea5'), ('\u0ea7',
+ '\u0ea7'), ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'), ('\u0eb2', '\u0eb2'), ('\u0ebd',
+ '\u0ebd'), ('\u0ec0', '\u0ec4'), ('\u0ec6', '\u0ec6'), ('\u0edc', '\u0edf'), ('\u0f00',
+ '\u0f00'), ('\u0f40', '\u0f47'), ('\u0f49', '\u0f6c'), ('\u0f88', '\u0f8c'), ('\u1000',
+ '\u102a'), ('\u103f', '\u103f'), ('\u1050', '\u1055'), ('\u105a', '\u105d'), ('\u1061',
+ '\u1061'), ('\u1065', '\u1066'), ('\u106e', '\u1070'), ('\u1075', '\u1081'), ('\u108e',
+ '\u108e'), ('\u10a0', '\u10c5'), ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'), ('\u10d0',
+ '\u10fa'), ('\u10fc', '\u10fc'), ('\u10fd', '\u1248'), ('\u124a', '\u124d'), ('\u1250',
+ '\u1256'), ('\u1258', '\u1258'), ('\u125a', '\u125d'), ('\u1260', '\u1288'), ('\u128a',
+ '\u128d'), ('\u1290', '\u12b0'), ('\u12b2', '\u12b5'), ('\u12b8', '\u12be'), ('\u12c0',
+ '\u12c0'), ('\u12c2', '\u12c5'), ('\u12c8', '\u12d6'), ('\u12d8', '\u1310'), ('\u1312',
+ '\u1315'), ('\u1318', '\u135a'), ('\u1380', '\u138f'), ('\u13a0', '\u13f4'), ('\u1401',
+ '\u166c'), ('\u166f', '\u167f'), ('\u1681', '\u169a'), ('\u16a0', '\u16ea'), ('\u16ee',
+ '\u16f0'), ('\u16f1', '\u16f8'), ('\u1700', '\u170c'), ('\u170e', '\u1711'), ('\u1720',
+ '\u1731'), ('\u1740', '\u1751'), ('\u1760', '\u176c'), ('\u176e', '\u1770'), ('\u1780',
+ '\u17b3'), ('\u17d7', '\u17d7'), ('\u17dc', '\u17dc'), ('\u1820', '\u1842'), ('\u1843',
+ '\u1843'), ('\u1844', '\u1877'), ('\u1880', '\u18a8'), ('\u18aa', '\u18aa'), ('\u18b0',
+ '\u18f5'), ('\u1900', '\u191e'), ('\u1950', '\u196d'), ('\u1970', '\u1974'), ('\u1980',
+ '\u19ab'), ('\u19c1', '\u19c7'), ('\u1a00', '\u1a16'), ('\u1a20', '\u1a54'), ('\u1aa7',
+ '\u1aa7'), ('\u1b05', '\u1b33'), ('\u1b45', '\u1b4b'), ('\u1b83', '\u1ba0'), ('\u1bae',
+ '\u1baf'), ('\u1bba', '\u1be5'), ('\u1c00', '\u1c23'), ('\u1c4d', '\u1c4f'), ('\u1c5a',
+ '\u1c77'), ('\u1c78', '\u1c7d'), ('\u1ce9', '\u1cec'), ('\u1cee', '\u1cf1'), ('\u1cf5',
+ '\u1cf6'), ('\u1d00', '\u1d2b'), ('\u1d2c', '\u1d6a'), ('\u1d6b', '\u1d77'), ('\u1d78',
+ '\u1d78'), ('\u1d79', '\u1d9a'), ('\u1d9b', '\u1dbf'), ('\u1e00', '\u1f15'), ('\u1f18',
+ '\u1f1d'), ('\u1f20', '\u1f45'), ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'), ('\u1f59',
+ '\u1f59'), ('\u1f5b', '\u1f5b'), ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'), ('\u1f80',
+ '\u1fb4'), ('\u1fb6', '\u1fbc'), ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'), ('\u1fc6',
+ '\u1fcc'), ('\u1fd0', '\u1fd3'), ('\u1fd6', '\u1fdb'), ('\u1fe0', '\u1fec'), ('\u1ff2',
+ '\u1ff4'), ('\u1ff6', '\u1ffc'), ('\u2071', '\u2071'), ('\u207f', '\u207f'), ('\u2090',
+ '\u209c'), ('\u2102', '\u2102'), ('\u2107', '\u2107'), ('\u210a', '\u2113'), ('\u2115',
+ '\u2115'), ('\u2118', '\u2118'), ('\u2119', '\u211d'), ('\u2124', '\u2124'), ('\u2126',
+ '\u2126'), ('\u2128', '\u2128'), ('\u212a', '\u212d'), ('\u212e', '\u212e'), ('\u212f',
+ '\u2134'), ('\u2135', '\u2138'), ('\u2139', '\u2139'), ('\u213c', '\u213f'), ('\u2145',
+ '\u2149'), ('\u214e', '\u214e'), ('\u2160', '\u2182'), ('\u2183', '\u2184'), ('\u2185',
+ '\u2188'), ('\u2c00', '\u2c2e'), ('\u2c30', '\u2c5e'), ('\u2c60', '\u2c7b'), ('\u2c7c',
+ '\u2c7d'), ('\u2c7e', '\u2ce4'), ('\u2ceb', '\u2cee'), ('\u2cf2', '\u2cf3'), ('\u2d00',
+ '\u2d25'), ('\u2d27', '\u2d27'), ('\u2d2d', '\u2d2d'), ('\u2d30', '\u2d67'), ('\u2d6f',
+ '\u2d6f'), ('\u2d80', '\u2d96'), ('\u2da0', '\u2da6'), ('\u2da8', '\u2dae'), ('\u2db0',
+ '\u2db6'), ('\u2db8', '\u2dbe'), ('\u2dc0', '\u2dc6'), ('\u2dc8', '\u2dce'), ('\u2dd0',
+ '\u2dd6'), ('\u2dd8', '\u2dde'), ('\u3005', '\u3005'), ('\u3006', '\u3006'), ('\u3007',
+ '\u3007'), ('\u3021', '\u3029'), ('\u3031', '\u3035'), ('\u3038', '\u303a'), ('\u303b',
+ '\u303b'), ('\u303c', '\u303c'), ('\u3041', '\u3096'), ('\u309d', '\u309e'), ('\u309f',
+ '\u309f'), ('\u30a1', '\u30fa'), ('\u30fc', '\u30fe'), ('\u30ff', '\u30ff'), ('\u3105',
+ '\u312d'), ('\u3131', '\u318e'), ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'), ('\u3400',
+ '\u4db5'), ('\u4e00', '\u9fcc'), ('\ua000', '\ua014'), ('\ua015', '\ua015'), ('\ua016',
+ '\ua48c'), ('\ua4d0', '\ua4f7'), ('\ua4f8', '\ua4fd'), ('\ua500', '\ua60b'), ('\ua60c',
+ '\ua60c'), ('\ua610', '\ua61f'), ('\ua62a', '\ua62b'), ('\ua640', '\ua66d'), ('\ua66e',
+ '\ua66e'), ('\ua67f', '\ua67f'), ('\ua680', '\ua69b'), ('\ua69c', '\ua69d'), ('\ua6a0',
+ '\ua6e5'), ('\ua6e6', '\ua6ef'), ('\ua717', '\ua71f'), ('\ua722', '\ua76f'), ('\ua770',
+ '\ua770'), ('\ua771', '\ua787'), ('\ua788', '\ua788'), ('\ua78b', '\ua78e'), ('\ua790',
+ '\ua7ad'), ('\ua7b0', '\ua7b1'), ('\ua7f7', '\ua7f7'), ('\ua7f8', '\ua7f9'), ('\ua7fa',
+ '\ua7fa'), ('\ua7fb', '\ua801'), ('\ua803', '\ua805'), ('\ua807', '\ua80a'), ('\ua80c',
+ '\ua822'), ('\ua840', '\ua873'), ('\ua882', '\ua8b3'), ('\ua8f2', '\ua8f7'), ('\ua8fb',
+ '\ua8fb'), ('\ua90a', '\ua925'), ('\ua930', '\ua946'), ('\ua960', '\ua97c'), ('\ua984',
+ '\ua9b2'), ('\ua9cf', '\ua9cf'), ('\ua9e0', '\ua9e4'), ('\ua9e6', '\ua9e6'), ('\ua9e7',
+ '\ua9ef'), ('\ua9fa', '\ua9fe'), ('\uaa00', '\uaa28'), ('\uaa40', '\uaa42'), ('\uaa44',
+ '\uaa4b'), ('\uaa60', '\uaa6f'), ('\uaa70', '\uaa70'), ('\uaa71', '\uaa76'), ('\uaa7a',
+ '\uaa7a'), ('\uaa7e', '\uaaaf'), ('\uaab1', '\uaab1'), ('\uaab5', '\uaab6'), ('\uaab9',
+ '\uaabd'), ('\uaac0', '\uaac0'), ('\uaac2', '\uaac2'), ('\uaadb', '\uaadc'), ('\uaadd',
+ '\uaadd'), ('\uaae0', '\uaaea'), ('\uaaf2', '\uaaf2'), ('\uaaf3', '\uaaf4'), ('\uab01',
+ '\uab06'), ('\uab09', '\uab0e'), ('\uab11', '\uab16'), ('\uab20', '\uab26'), ('\uab28',
+ '\uab2e'), ('\uab30', '\uab5a'), ('\uab5c', '\uab5f'), ('\uab64', '\uab65'), ('\uabc0',
+ '\uabe2'), ('\uac00', '\ud7a3'), ('\ud7b0', '\ud7c6'), ('\ud7cb', '\ud7fb'), ('\uf900',
+ '\ufa6d'), ('\ufa70', '\ufad9'), ('\ufb00', '\ufb06'), ('\ufb13', '\ufb17'), ('\ufb1d',
+ '\ufb1d'), ('\ufb1f', '\ufb28'), ('\ufb2a', '\ufb36'), ('\ufb38', '\ufb3c'), ('\ufb3e',
+ '\ufb3e'), ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'), ('\ufb46', '\ufbb1'), ('\ufbd3',
+ '\ufc5d'), ('\ufc64', '\ufd3d'), ('\ufd50', '\ufd8f'), ('\ufd92', '\ufdc7'), ('\ufdf0',
+ '\ufdf9'), ('\ufe71', '\ufe71'), ('\ufe73', '\ufe73'), ('\ufe77', '\ufe77'), ('\ufe79',
+ '\ufe79'), ('\ufe7b', '\ufe7b'), ('\ufe7d', '\ufe7d'), ('\ufe7f', '\ufefc'), ('\uff21',
+ '\uff3a'), ('\uff41', '\uff5a'), ('\uff66', '\uff6f'), ('\uff70', '\uff70'), ('\uff71',
+ '\uff9d'), ('\uffa0', '\uffbe'), ('\uffc2', '\uffc7'), ('\uffca', '\uffcf'), ('\uffd2',
+ '\uffd7'), ('\uffda', '\uffdc'), ('\U00010000', '\U0001000b'), ('\U0001000d', '\U00010026'),
+ ('\U00010028', '\U0001003a'), ('\U0001003c', '\U0001003d'), ('\U0001003f', '\U0001004d'),
+ ('\U00010050', '\U0001005d'), ('\U00010080', '\U000100fa'), ('\U00010140', '\U00010174'),
+ ('\U00010280', '\U0001029c'), ('\U000102a0', '\U000102d0'), ('\U00010300', '\U0001031f'),
+ ('\U00010330', '\U00010340'), ('\U00010341', '\U00010341'), ('\U00010342', '\U00010349'),
+ ('\U0001034a', '\U0001034a'), ('\U00010350', '\U00010375'), ('\U00010380', '\U0001039d'),
+ ('\U000103a0', '\U000103c3'), ('\U000103c8', '\U000103cf'), ('\U000103d1', '\U000103d5'),
+ ('\U00010400', '\U0001044f'), ('\U00010450', '\U0001049d'), ('\U00010500', '\U00010527'),
+ ('\U00010530', '\U00010563'), ('\U00010600', '\U00010736'), ('\U00010740', '\U00010755'),
+ ('\U00010760', '\U00010767'), ('\U00010800', '\U00010805'), ('\U00010808', '\U00010808'),
+ ('\U0001080a', '\U00010835'), ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'),
+ ('\U0001083f', '\U00010855'), ('\U00010860', '\U00010876'), ('\U00010880', '\U0001089e'),
+ ('\U00010900', '\U00010915'), ('\U00010920', '\U00010939'), ('\U00010980', '\U000109b7'),
+ ('\U000109be', '\U000109bf'), ('\U00010a00', '\U00010a00'), ('\U00010a10', '\U00010a13'),
+ ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'), ('\U00010a60', '\U00010a7c'),
+ ('\U00010a80', '\U00010a9c'), ('\U00010ac0', '\U00010ac7'), ('\U00010ac9', '\U00010ae4'),
+ ('\U00010b00', '\U00010b35'), ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'),
+ ('\U00010b80', '\U00010b91'), ('\U00010c00', '\U00010c48'), ('\U00011003', '\U00011037'),
+ ('\U00011083', '\U000110af'), ('\U000110d0', '\U000110e8'), ('\U00011103', '\U00011126'),
+ ('\U00011150', '\U00011172'), ('\U00011176', '\U00011176'), ('\U00011183', '\U000111b2'),
+ ('\U000111c1', '\U000111c4'), ('\U000111da', '\U000111da'), ('\U00011200', '\U00011211'),
+ ('\U00011213', '\U0001122b'), ('\U000112b0', '\U000112de'), ('\U00011305', '\U0001130c'),
+ ('\U0001130f', '\U00011310'), ('\U00011313', '\U00011328'), ('\U0001132a', '\U00011330'),
+ ('\U00011332', '\U00011333'), ('\U00011335', '\U00011339'), ('\U0001133d', '\U0001133d'),
+ ('\U0001135d', '\U00011361'), ('\U00011480', '\U000114af'), ('\U000114c4', '\U000114c5'),
+ ('\U000114c7', '\U000114c7'), ('\U00011580', '\U000115ae'), ('\U00011600', '\U0001162f'),
+ ('\U00011644', '\U00011644'), ('\U00011680', '\U000116aa'), ('\U000118a0', '\U000118df'),
+ ('\U000118ff', '\U000118ff'), ('\U00011ac0', '\U00011af8'), ('\U00012000', '\U00012398'),
+ ('\U00012400', '\U0001246e'), ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'),
+ ('\U00016a40', '\U00016a5e'), ('\U00016ad0', '\U00016aed'), ('\U00016b00', '\U00016b2f'),
+ ('\U00016b40', '\U00016b43'), ('\U00016b63', '\U00016b77'), ('\U00016b7d', '\U00016b8f'),
+ ('\U00016f00', '\U00016f44'), ('\U00016f50', '\U00016f50'), ('\U00016f93', '\U00016f9f'),
+ ('\U0001b000', '\U0001b001'), ('\U0001bc00', '\U0001bc6a'), ('\U0001bc70', '\U0001bc7c'),
+ ('\U0001bc80', '\U0001bc88'), ('\U0001bc90', '\U0001bc99'), ('\U0001d400', '\U0001d454'),
+ ('\U0001d456', '\U0001d49c'), ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'),
+ ('\U0001d4a5', '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b9'),
+ ('\U0001d4bb', '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d505'),
+ ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'), ('\U0001d516', '\U0001d51c'),
+ ('\U0001d51e', '\U0001d539'), ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'),
+ ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'), ('\U0001d552', '\U0001d6a5'),
+ ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc', '\U0001d6fa'),
+ ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d734'), ('\U0001d736', '\U0001d74e'),
+ ('\U0001d750', '\U0001d76e'), ('\U0001d770', '\U0001d788'), ('\U0001d78a', '\U0001d7a8'),
+ ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb'), ('\U0001e800', '\U0001e8c4'),
+ ('\U0001ee00', '\U0001ee03'), ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'),
+ ('\U0001ee24', '\U0001ee24'), ('\U0001ee27', '\U0001ee27'), ('\U0001ee29', '\U0001ee32'),
+ ('\U0001ee34', '\U0001ee37'), ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'),
+ ('\U0001ee42', '\U0001ee42'), ('\U0001ee47', '\U0001ee47'), ('\U0001ee49', '\U0001ee49'),
+ ('\U0001ee4b', '\U0001ee4b'), ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'),
+ ('\U0001ee54', '\U0001ee54'), ('\U0001ee57', '\U0001ee57'), ('\U0001ee59', '\U0001ee59'),
+ ('\U0001ee5b', '\U0001ee5b'), ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'),
+ ('\U0001ee61', '\U0001ee62'), ('\U0001ee64', '\U0001ee64'), ('\U0001ee67', '\U0001ee6a'),
+ ('\U0001ee6c', '\U0001ee72'), ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'),
+ ('\U0001ee7e', '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'), ('\U0001ee8b', '\U0001ee9b'),
+ ('\U0001eea1', '\U0001eea3'), ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'),
+ ('\U00020000', '\U0002a6d6'), ('\U0002a700', '\U0002b734'), ('\U0002b740', '\U0002b81d'),
+ ('\U0002f800', '\U0002fa1d')
+ ];
+
+ pub fn XID_Start(c: char) -> bool {
+ super::bsearch_range_table(c, XID_Start_table)
+ }
+
+}
+
+pub mod script {
+ pub static Arabic_table: &'static [(char, char)] = &[
+ ('\u0600', '\u0604'), ('\u0606', '\u0608'), ('\u0609', '\u060a'), ('\u060b', '\u060b'),
+ ('\u060d', '\u060d'), ('\u060e', '\u060f'), ('\u0610', '\u061a'), ('\u061e', '\u061e'),
+ ('\u0620', '\u063f'), ('\u0641', '\u064a'), ('\u0656', '\u065f'), ('\u066a', '\u066d'),
+ ('\u066e', '\u066f'), ('\u0671', '\u06d3'), ('\u06d4', '\u06d4'), ('\u06d5', '\u06d5'),
+ ('\u06d6', '\u06dc'), ('\u06de', '\u06de'), ('\u06df', '\u06e4'), ('\u06e5', '\u06e6'),
+ ('\u06e7', '\u06e8'), ('\u06e9', '\u06e9'), ('\u06ea', '\u06ed'), ('\u06ee', '\u06ef'),
+ ('\u06f0', '\u06f9'), ('\u06fa', '\u06fc'), ('\u06fd', '\u06fe'), ('\u06ff', '\u06ff'),
+ ('\u0750', '\u077f'), ('\u08a0', '\u08b2'), ('\u08e4', '\u08ff'), ('\ufb50', '\ufbb1'),
+ ('\ufbb2', '\ufbc1'), ('\ufbd3', '\ufd3d'), ('\ufd50', '\ufd8f'), ('\ufd92', '\ufdc7'),
+ ('\ufdf0', '\ufdfb'), ('\ufdfc', '\ufdfc'), ('\ufdfd', '\ufdfd'), ('\ufe70', '\ufe74'),
+ ('\ufe76', '\ufefc'), ('\U00010e60', '\U00010e7e'), ('\U0001ee00', '\U0001ee03'),
+ ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'), ('\U0001ee24', '\U0001ee24'),
+ ('\U0001ee27', '\U0001ee27'), ('\U0001ee29', '\U0001ee32'), ('\U0001ee34', '\U0001ee37'),
+ ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'), ('\U0001ee42', '\U0001ee42'),
+ ('\U0001ee47', '\U0001ee47'), ('\U0001ee49', '\U0001ee49'), ('\U0001ee4b', '\U0001ee4b'),
+ ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'), ('\U0001ee54', '\U0001ee54'),
+ ('\U0001ee57', '\U0001ee57'), ('\U0001ee59', '\U0001ee59'), ('\U0001ee5b', '\U0001ee5b'),
+ ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'), ('\U0001ee61', '\U0001ee62'),
+ ('\U0001ee64', '\U0001ee64'), ('\U0001ee67', '\U0001ee6a'), ('\U0001ee6c', '\U0001ee72'),
+ ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'), ('\U0001ee7e', '\U0001ee7e'),
+ ('\U0001ee80', '\U0001ee89'), ('\U0001ee8b', '\U0001ee9b'), ('\U0001eea1', '\U0001eea3'),
+ ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'), ('\U0001eef0', '\U0001eef1')
+ ];
+
+ pub static Armenian_table: &'static [(char, char)] = &[
+ ('\u0531', '\u0556'), ('\u0559', '\u0559'), ('\u055a', '\u055f'), ('\u0561', '\u0587'),
+ ('\u058a', '\u058a'), ('\u058d', '\u058e'), ('\u058f', '\u058f'), ('\ufb13', '\ufb17')
+ ];
+
+ pub static Avestan_table: &'static [(char, char)] = &[
+ ('\U00010b00', '\U00010b35'), ('\U00010b39', '\U00010b3f')
+ ];
+
+ pub static Balinese_table: &'static [(char, char)] = &[
+ ('\u1b00', '\u1b03'), ('\u1b04', '\u1b04'), ('\u1b05', '\u1b33'), ('\u1b34', '\u1b34'),
+ ('\u1b35', '\u1b35'), ('\u1b36', '\u1b3a'), ('\u1b3b', '\u1b3b'), ('\u1b3c', '\u1b3c'),
+ ('\u1b3d', '\u1b41'), ('\u1b42', '\u1b42'), ('\u1b43', '\u1b44'), ('\u1b45', '\u1b4b'),
+ ('\u1b50', '\u1b59'), ('\u1b5a', '\u1b60'), ('\u1b61', '\u1b6a'), ('\u1b6b', '\u1b73'),
+ ('\u1b74', '\u1b7c')
+ ];
+
+ pub static Bamum_table: &'static [(char, char)] = &[
+ ('\ua6a0', '\ua6e5'), ('\ua6e6', '\ua6ef'), ('\ua6f0', '\ua6f1'), ('\ua6f2', '\ua6f7'),
+ ('\U00016800', '\U00016a38')
+ ];
+
+ pub static Bassa_Vah_table: &'static [(char, char)] = &[
+ ('\U00016ad0', '\U00016aed'), ('\U00016af0', '\U00016af4'), ('\U00016af5', '\U00016af5')
+ ];
+
+ pub static Batak_table: &'static [(char, char)] = &[
+ ('\u1bc0', '\u1be5'), ('\u1be6', '\u1be6'), ('\u1be7', '\u1be7'), ('\u1be8', '\u1be9'),
+ ('\u1bea', '\u1bec'), ('\u1bed', '\u1bed'), ('\u1bee', '\u1bee'), ('\u1bef', '\u1bf1'),
+ ('\u1bf2', '\u1bf3'), ('\u1bfc', '\u1bff')
+ ];
+
+ pub static Bengali_table: &'static [(char, char)] = &[
+ ('\u0980', '\u0980'), ('\u0981', '\u0981'), ('\u0982', '\u0983'), ('\u0985', '\u098c'),
+ ('\u098f', '\u0990'), ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'), ('\u09b2', '\u09b2'),
+ ('\u09b6', '\u09b9'), ('\u09bc', '\u09bc'), ('\u09bd', '\u09bd'), ('\u09be', '\u09c0'),
+ ('\u09c1', '\u09c4'), ('\u09c7', '\u09c8'), ('\u09cb', '\u09cc'), ('\u09cd', '\u09cd'),
+ ('\u09ce', '\u09ce'), ('\u09d7', '\u09d7'), ('\u09dc', '\u09dd'), ('\u09df', '\u09e1'),
+ ('\u09e2', '\u09e3'), ('\u09e6', '\u09ef'), ('\u09f0', '\u09f1'), ('\u09f2', '\u09f3'),
+ ('\u09f4', '\u09f9'), ('\u09fa', '\u09fa'), ('\u09fb', '\u09fb')
+ ];
+
+ pub static Bopomofo_table: &'static [(char, char)] = &[
+ ('\u02ea', '\u02eb'), ('\u3105', '\u312d'), ('\u31a0', '\u31ba')
+ ];
+
+ pub static Brahmi_table: &'static [(char, char)] = &[
+ ('\U00011000', '\U00011000'), ('\U00011001', '\U00011001'), ('\U00011002', '\U00011002'),
+ ('\U00011003', '\U00011037'), ('\U00011038', '\U00011046'), ('\U00011047', '\U0001104d'),
+ ('\U00011052', '\U00011065'), ('\U00011066', '\U0001106f'), ('\U0001107f', '\U0001107f')
+ ];
+
+ pub static Braille_table: &'static [(char, char)] = &[
+ ('\u2800', '\u28ff')
+ ];
+
+ pub static Buginese_table: &'static [(char, char)] = &[
+ ('\u1a00', '\u1a16'), ('\u1a17', '\u1a18'), ('\u1a19', '\u1a1a'), ('\u1a1b', '\u1a1b'),
+ ('\u1a1e', '\u1a1f')
+ ];
+
+ pub static Buhid_table: &'static [(char, char)] = &[
+ ('\u1740', '\u1751'), ('\u1752', '\u1753')
+ ];
+
+ pub static Canadian_Aboriginal_table: &'static [(char, char)] = &[
+ ('\u1400', '\u1400'), ('\u1401', '\u166c'), ('\u166d', '\u166e'), ('\u166f', '\u167f'),
+ ('\u18b0', '\u18f5')
+ ];
+
+ pub static Carian_table: &'static [(char, char)] = &[
+ ('\U000102a0', '\U000102d0')
+ ];
+
+ pub static Caucasian_Albanian_table: &'static [(char, char)] = &[
+ ('\U00010530', '\U00010563'), ('\U0001056f', '\U0001056f')
+ ];
+
+ pub static Chakma_table: &'static [(char, char)] = &[
+ ('\U00011100', '\U00011102'), ('\U00011103', '\U00011126'), ('\U00011127', '\U0001112b'),
+ ('\U0001112c', '\U0001112c'), ('\U0001112d', '\U00011134'), ('\U00011136', '\U0001113f'),
+ ('\U00011140', '\U00011143')
+ ];
+
+ pub static Cham_table: &'static [(char, char)] = &[
+ ('\uaa00', '\uaa28'), ('\uaa29', '\uaa2e'), ('\uaa2f', '\uaa30'), ('\uaa31', '\uaa32'),
+ ('\uaa33', '\uaa34'), ('\uaa35', '\uaa36'), ('\uaa40', '\uaa42'), ('\uaa43', '\uaa43'),
+ ('\uaa44', '\uaa4b'), ('\uaa4c', '\uaa4c'), ('\uaa4d', '\uaa4d'), ('\uaa50', '\uaa59'),
+ ('\uaa5c', '\uaa5f')
+ ];
+
+ pub static Cherokee_table: &'static [(char, char)] = &[
+ ('\u13a0', '\u13f4')
+ ];
+
+ pub static Common_table: &'static [(char, char)] = &[
+ ('\x00', '\x1f'), ('\x20', '\x20'), ('\x21', '\x23'), ('\x24', '\x24'), ('\x25', '\x27'),
+ ('\x28', '\x28'), ('\x29', '\x29'), ('\x2a', '\x2a'), ('\x2b', '\x2b'), ('\x2c', '\x2c'),
+ ('\x2d', '\x2d'), ('\x2e', '\x2f'), ('\x30', '\x39'), ('\x3a', '\x3b'), ('\x3c', '\x3e'),
+ ('\x3f', '\x40'), ('\x5b', '\x5b'), ('\x5c', '\x5c'), ('\x5d', '\x5d'), ('\x5e', '\x5e'),
+ ('\x5f', '\x5f'), ('\x60', '\x60'), ('\x7b', '\x7b'), ('\x7c', '\x7c'), ('\x7d', '\x7d'),
+ ('\x7e', '\x7e'), ('\x7f', '\x9f'), ('\xa0', '\xa0'), ('\xa1', '\xa1'), ('\xa2', '\xa5'),
+ ('\xa6', '\xa6'), ('\xa7', '\xa7'), ('\xa8', '\xa8'), ('\xa9', '\xa9'), ('\xab', '\xab'),
+ ('\xac', '\xac'), ('\xad', '\xad'), ('\xae', '\xae'), ('\xaf', '\xaf'), ('\xb0', '\xb0'),
+ ('\xb1', '\xb1'), ('\xb2', '\xb3'), ('\xb4', '\xb4'), ('\xb5', '\xb5'), ('\xb6', '\xb7'),
+ ('\xb8', '\xb8'), ('\xb9', '\xb9'), ('\xbb', '\xbb'), ('\xbc', '\xbe'), ('\xbf', '\xbf'),
+ ('\xd7', '\xd7'), ('\xf7', '\xf7'), ('\u02b9', '\u02c1'), ('\u02c2', '\u02c5'), ('\u02c6',
+ '\u02d1'), ('\u02d2', '\u02df'), ('\u02e5', '\u02e9'), ('\u02ec', '\u02ec'), ('\u02ed',
+ '\u02ed'), ('\u02ee', '\u02ee'), ('\u02ef', '\u02ff'), ('\u0374', '\u0374'), ('\u037e',
+ '\u037e'), ('\u0385', '\u0385'), ('\u0387', '\u0387'), ('\u0589', '\u0589'), ('\u0605',
+ '\u0605'), ('\u060c', '\u060c'), ('\u061b', '\u061b'), ('\u061c', '\u061c'), ('\u061f',
+ '\u061f'), ('\u0640', '\u0640'), ('\u0660', '\u0669'), ('\u06dd', '\u06dd'), ('\u0964',
+ '\u0965'), ('\u0e3f', '\u0e3f'), ('\u0fd5', '\u0fd8'), ('\u10fb', '\u10fb'), ('\u16eb',
+ '\u16ed'), ('\u1735', '\u1736'), ('\u1802', '\u1803'), ('\u1805', '\u1805'), ('\u1cd3',
+ '\u1cd3'), ('\u1ce1', '\u1ce1'), ('\u1ce9', '\u1cec'), ('\u1cee', '\u1cf1'), ('\u1cf2',
+ '\u1cf3'), ('\u1cf5', '\u1cf6'), ('\u2000', '\u200a'), ('\u200b', '\u200b'), ('\u200e',
+ '\u200f'), ('\u2010', '\u2015'), ('\u2016', '\u2017'), ('\u2018', '\u2018'), ('\u2019',
+ '\u2019'), ('\u201a', '\u201a'), ('\u201b', '\u201c'), ('\u201d', '\u201d'), ('\u201e',
+ '\u201e'), ('\u201f', '\u201f'), ('\u2020', '\u2027'), ('\u2028', '\u2028'), ('\u2029',
+ '\u2029'), ('\u202a', '\u202e'), ('\u202f', '\u202f'), ('\u2030', '\u2038'), ('\u2039',
+ '\u2039'), ('\u203a', '\u203a'), ('\u203b', '\u203e'), ('\u203f', '\u2040'), ('\u2041',
+ '\u2043'), ('\u2044', '\u2044'), ('\u2045', '\u2045'), ('\u2046', '\u2046'), ('\u2047',
+ '\u2051'), ('\u2052', '\u2052'), ('\u2053', '\u2053'), ('\u2054', '\u2054'), ('\u2055',
+ '\u205e'), ('\u205f', '\u205f'), ('\u2060', '\u2064'), ('\u2066', '\u206f'), ('\u2070',
+ '\u2070'), ('\u2074', '\u2079'), ('\u207a', '\u207c'), ('\u207d', '\u207d'), ('\u207e',
+ '\u207e'), ('\u2080', '\u2089'), ('\u208a', '\u208c'), ('\u208d', '\u208d'), ('\u208e',
+ '\u208e'), ('\u20a0', '\u20bd'), ('\u2100', '\u2101'), ('\u2102', '\u2102'), ('\u2103',
+ '\u2106'), ('\u2107', '\u2107'), ('\u2108', '\u2109'), ('\u210a', '\u2113'), ('\u2114',
+ '\u2114'), ('\u2115', '\u2115'), ('\u2116', '\u2117'), ('\u2118', '\u2118'), ('\u2119',
+ '\u211d'), ('\u211e', '\u2123'), ('\u2124', '\u2124'), ('\u2125', '\u2125'), ('\u2127',
+ '\u2127'), ('\u2128', '\u2128'), ('\u2129', '\u2129'), ('\u212c', '\u212d'), ('\u212e',
+ '\u212e'), ('\u212f', '\u2131'), ('\u2133', '\u2134'), ('\u2135', '\u2138'), ('\u2139',
+ '\u2139'), ('\u213a', '\u213b'), ('\u213c', '\u213f'), ('\u2140', '\u2144'), ('\u2145',
+ '\u2149'), ('\u214a', '\u214a'), ('\u214b', '\u214b'), ('\u214c', '\u214d'), ('\u214f',
+ '\u214f'), ('\u2150', '\u215f'), ('\u2189', '\u2189'), ('\u2190', '\u2194'), ('\u2195',
+ '\u2199'), ('\u219a', '\u219b'), ('\u219c', '\u219f'), ('\u21a0', '\u21a0'), ('\u21a1',
+ '\u21a2'), ('\u21a3', '\u21a3'), ('\u21a4', '\u21a5'), ('\u21a6', '\u21a6'), ('\u21a7',
+ '\u21ad'), ('\u21ae', '\u21ae'), ('\u21af', '\u21cd'), ('\u21ce', '\u21cf'), ('\u21d0',
+ '\u21d1'), ('\u21d2', '\u21d2'), ('\u21d3', '\u21d3'), ('\u21d4', '\u21d4'), ('\u21d5',
+ '\u21f3'), ('\u21f4', '\u22ff'), ('\u2300', '\u2307'), ('\u2308', '\u2308'), ('\u2309',
+ '\u2309'), ('\u230a', '\u230a'), ('\u230b', '\u230b'), ('\u230c', '\u231f'), ('\u2320',
+ '\u2321'), ('\u2322', '\u2328'), ('\u2329', '\u2329'), ('\u232a', '\u232a'), ('\u232b',
+ '\u237b'), ('\u237c', '\u237c'), ('\u237d', '\u239a'), ('\u239b', '\u23b3'), ('\u23b4',
+ '\u23db'), ('\u23dc', '\u23e1'), ('\u23e2', '\u23fa'), ('\u2400', '\u2426'), ('\u2440',
+ '\u244a'), ('\u2460', '\u249b'), ('\u249c', '\u24e9'), ('\u24ea', '\u24ff'), ('\u2500',
+ '\u25b6'), ('\u25b7', '\u25b7'), ('\u25b8', '\u25c0'), ('\u25c1', '\u25c1'), ('\u25c2',
+ '\u25f7'), ('\u25f8', '\u25ff'), ('\u2600', '\u266e'), ('\u266f', '\u266f'), ('\u2670',
+ '\u2767'), ('\u2768', '\u2768'), ('\u2769', '\u2769'), ('\u276a', '\u276a'), ('\u276b',
+ '\u276b'), ('\u276c', '\u276c'), ('\u276d', '\u276d'), ('\u276e', '\u276e'), ('\u276f',
+ '\u276f'), ('\u2770', '\u2770'), ('\u2771', '\u2771'), ('\u2772', '\u2772'), ('\u2773',
+ '\u2773'), ('\u2774', '\u2774'), ('\u2775', '\u2775'), ('\u2776', '\u2793'), ('\u2794',
+ '\u27bf'), ('\u27c0', '\u27c4'), ('\u27c5', '\u27c5'), ('\u27c6', '\u27c6'), ('\u27c7',
+ '\u27e5'), ('\u27e6', '\u27e6'), ('\u27e7', '\u27e7'), ('\u27e8', '\u27e8'), ('\u27e9',
+ '\u27e9'), ('\u27ea', '\u27ea'), ('\u27eb', '\u27eb'), ('\u27ec', '\u27ec'), ('\u27ed',
+ '\u27ed'), ('\u27ee', '\u27ee'), ('\u27ef', '\u27ef'), ('\u27f0', '\u27ff'), ('\u2900',
+ '\u2982'), ('\u2983', '\u2983'), ('\u2984', '\u2984'), ('\u2985', '\u2985'), ('\u2986',
+ '\u2986'), ('\u2987', '\u2987'), ('\u2988', '\u2988'), ('\u2989', '\u2989'), ('\u298a',
+ '\u298a'), ('\u298b', '\u298b'), ('\u298c', '\u298c'), ('\u298d', '\u298d'), ('\u298e',
+ '\u298e'), ('\u298f', '\u298f'), ('\u2990', '\u2990'), ('\u2991', '\u2991'), ('\u2992',
+ '\u2992'), ('\u2993', '\u2993'), ('\u2994', '\u2994'), ('\u2995', '\u2995'), ('\u2996',
+ '\u2996'), ('\u2997', '\u2997'), ('\u2998', '\u2998'), ('\u2999', '\u29d7'), ('\u29d8',
+ '\u29d8'), ('\u29d9', '\u29d9'), ('\u29da', '\u29da'), ('\u29db', '\u29db'), ('\u29dc',
+ '\u29fb'), ('\u29fc', '\u29fc'), ('\u29fd', '\u29fd'), ('\u29fe', '\u2aff'), ('\u2b00',
+ '\u2b2f'), ('\u2b30', '\u2b44'), ('\u2b45', '\u2b46'), ('\u2b47', '\u2b4c'), ('\u2b4d',
+ '\u2b73'), ('\u2b76', '\u2b95'), ('\u2b98', '\u2bb9'), ('\u2bbd', '\u2bc8'), ('\u2bca',
+ '\u2bd1'), ('\u2e00', '\u2e01'), ('\u2e02', '\u2e02'), ('\u2e03', '\u2e03'), ('\u2e04',
+ '\u2e04'), ('\u2e05', '\u2e05'), ('\u2e06', '\u2e08'), ('\u2e09', '\u2e09'), ('\u2e0a',
+ '\u2e0a'), ('\u2e0b', '\u2e0b'), ('\u2e0c', '\u2e0c'), ('\u2e0d', '\u2e0d'), ('\u2e0e',
+ '\u2e16'), ('\u2e17', '\u2e17'), ('\u2e18', '\u2e19'), ('\u2e1a', '\u2e1a'), ('\u2e1b',
+ '\u2e1b'), ('\u2e1c', '\u2e1c'), ('\u2e1d', '\u2e1d'), ('\u2e1e', '\u2e1f'), ('\u2e20',
+ '\u2e20'), ('\u2e21', '\u2e21'), ('\u2e22', '\u2e22'), ('\u2e23', '\u2e23'), ('\u2e24',
+ '\u2e24'), ('\u2e25', '\u2e25'), ('\u2e26', '\u2e26'), ('\u2e27', '\u2e27'), ('\u2e28',
+ '\u2e28'), ('\u2e29', '\u2e29'), ('\u2e2a', '\u2e2e'), ('\u2e2f', '\u2e2f'), ('\u2e30',
+ '\u2e39'), ('\u2e3a', '\u2e3b'), ('\u2e3c', '\u2e3f'), ('\u2e40', '\u2e40'), ('\u2e41',
+ '\u2e41'), ('\u2e42', '\u2e42'), ('\u2ff0', '\u2ffb'), ('\u3000', '\u3000'), ('\u3001',
+ '\u3003'), ('\u3004', '\u3004'), ('\u3006', '\u3006'), ('\u3008', '\u3008'), ('\u3009',
+ '\u3009'), ('\u300a', '\u300a'), ('\u300b', '\u300b'), ('\u300c', '\u300c'), ('\u300d',
+ '\u300d'), ('\u300e', '\u300e'), ('\u300f', '\u300f'), ('\u3010', '\u3010'), ('\u3011',
+ '\u3011'), ('\u3012', '\u3013'), ('\u3014', '\u3014'), ('\u3015', '\u3015'), ('\u3016',
+ '\u3016'), ('\u3017', '\u3017'), ('\u3018', '\u3018'), ('\u3019', '\u3019'), ('\u301a',
+ '\u301a'), ('\u301b', '\u301b'), ('\u301c', '\u301c'), ('\u301d', '\u301d'), ('\u301e',
+ '\u301f'), ('\u3020', '\u3020'), ('\u3030', '\u3030'), ('\u3031', '\u3035'), ('\u3036',
+ '\u3037'), ('\u303c', '\u303c'), ('\u303d', '\u303d'), ('\u303e', '\u303f'), ('\u309b',
+ '\u309c'), ('\u30a0', '\u30a0'), ('\u30fb', '\u30fb'), ('\u30fc', '\u30fc'), ('\u3190',
+ '\u3191'), ('\u3192', '\u3195'), ('\u3196', '\u319f'), ('\u31c0', '\u31e3'), ('\u3220',
+ '\u3229'), ('\u322a', '\u3247'), ('\u3248', '\u324f'), ('\u3250', '\u3250'), ('\u3251',
+ '\u325f'), ('\u327f', '\u327f'), ('\u3280', '\u3289'), ('\u328a', '\u32b0'), ('\u32b1',
+ '\u32bf'), ('\u32c0', '\u32cf'), ('\u3358', '\u33ff'), ('\u4dc0', '\u4dff'), ('\ua700',
+ '\ua716'), ('\ua717', '\ua71f'), ('\ua720', '\ua721'), ('\ua788', '\ua788'), ('\ua789',
+ '\ua78a'), ('\ua830', '\ua835'), ('\ua836', '\ua837'), ('\ua838', '\ua838'), ('\ua839',
+ '\ua839'), ('\ua92e', '\ua92e'), ('\ua9cf', '\ua9cf'), ('\uab5b', '\uab5b'), ('\ufd3e',
+ '\ufd3e'), ('\ufd3f', '\ufd3f'), ('\ufe10', '\ufe16'), ('\ufe17', '\ufe17'), ('\ufe18',
+ '\ufe18'), ('\ufe19', '\ufe19'), ('\ufe30', '\ufe30'), ('\ufe31', '\ufe32'), ('\ufe33',
+ '\ufe34'), ('\ufe35', '\ufe35'), ('\ufe36', '\ufe36'), ('\ufe37', '\ufe37'), ('\ufe38',
+ '\ufe38'), ('\ufe39', '\ufe39'), ('\ufe3a', '\ufe3a'), ('\ufe3b', '\ufe3b'), ('\ufe3c',
+ '\ufe3c'), ('\ufe3d', '\ufe3d'), ('\ufe3e', '\ufe3e'), ('\ufe3f', '\ufe3f'), ('\ufe40',
+ '\ufe40'), ('\ufe41', '\ufe41'), ('\ufe42', '\ufe42'), ('\ufe43', '\ufe43'), ('\ufe44',
+ '\ufe44'), ('\ufe45', '\ufe46'), ('\ufe47', '\ufe47'), ('\ufe48', '\ufe48'), ('\ufe49',
+ '\ufe4c'), ('\ufe4d', '\ufe4f'), ('\ufe50', '\ufe52'), ('\ufe54', '\ufe57'), ('\ufe58',
+ '\ufe58'), ('\ufe59', '\ufe59'), ('\ufe5a', '\ufe5a'), ('\ufe5b', '\ufe5b'), ('\ufe5c',
+ '\ufe5c'), ('\ufe5d', '\ufe5d'), ('\ufe5e', '\ufe5e'), ('\ufe5f', '\ufe61'), ('\ufe62',
+ '\ufe62'), ('\ufe63', '\ufe63'), ('\ufe64', '\ufe66'), ('\ufe68', '\ufe68'), ('\ufe69',
+ '\ufe69'), ('\ufe6a', '\ufe6b'), ('\ufeff', '\ufeff'), ('\uff01', '\uff03'), ('\uff04',
+ '\uff04'), ('\uff05', '\uff07'), ('\uff08', '\uff08'), ('\uff09', '\uff09'), ('\uff0a',
+ '\uff0a'), ('\uff0b', '\uff0b'), ('\uff0c', '\uff0c'), ('\uff0d', '\uff0d'), ('\uff0e',
+ '\uff0f'), ('\uff10', '\uff19'), ('\uff1a', '\uff1b'), ('\uff1c', '\uff1e'), ('\uff1f',
+ '\uff20'), ('\uff3b', '\uff3b'), ('\uff3c', '\uff3c'), ('\uff3d', '\uff3d'), ('\uff3e',
+ '\uff3e'), ('\uff3f', '\uff3f'), ('\uff40', '\uff40'), ('\uff5b', '\uff5b'), ('\uff5c',
+ '\uff5c'), ('\uff5d', '\uff5d'), ('\uff5e', '\uff5e'), ('\uff5f', '\uff5f'), ('\uff60',
+ '\uff60'), ('\uff61', '\uff61'), ('\uff62', '\uff62'), ('\uff63', '\uff63'), ('\uff64',
+ '\uff65'), ('\uff70', '\uff70'), ('\uff9e', '\uff9f'), ('\uffe0', '\uffe1'), ('\uffe2',
+ '\uffe2'), ('\uffe3', '\uffe3'), ('\uffe4', '\uffe4'), ('\uffe5', '\uffe6'), ('\uffe8',
+ '\uffe8'), ('\uffe9', '\uffec'), ('\uffed', '\uffee'), ('\ufff9', '\ufffb'), ('\ufffc',
+ '\ufffd'), ('\U00010100', '\U00010102'), ('\U00010107', '\U00010133'), ('\U00010137',
+ '\U0001013f'), ('\U00010190', '\U0001019b'), ('\U000101d0', '\U000101fc'), ('\U000102e1',
+ '\U000102fb'), ('\U0001bca0', '\U0001bca3'), ('\U0001d000', '\U0001d0f5'), ('\U0001d100',
+ '\U0001d126'), ('\U0001d129', '\U0001d164'), ('\U0001d165', '\U0001d166'), ('\U0001d16a',
+ '\U0001d16c'), ('\U0001d16d', '\U0001d172'), ('\U0001d173', '\U0001d17a'), ('\U0001d183',
+ '\U0001d184'), ('\U0001d18c', '\U0001d1a9'), ('\U0001d1ae', '\U0001d1dd'), ('\U0001d300',
+ '\U0001d356'), ('\U0001d360', '\U0001d371'), ('\U0001d400', '\U0001d454'), ('\U0001d456',
+ '\U0001d49c'), ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2', '\U0001d4a2'), ('\U0001d4a5',
+ '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae', '\U0001d4b9'), ('\U0001d4bb',
+ '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5', '\U0001d505'), ('\U0001d507',
+ '\U0001d50a'), ('\U0001d50d', '\U0001d514'), ('\U0001d516', '\U0001d51c'), ('\U0001d51e',
+ '\U0001d539'), ('\U0001d53b', '\U0001d53e'), ('\U0001d540', '\U0001d544'), ('\U0001d546',
+ '\U0001d546'), ('\U0001d54a', '\U0001d550'), ('\U0001d552', '\U0001d6a5'), ('\U0001d6a8',
+ '\U0001d6c0'), ('\U0001d6c1', '\U0001d6c1'), ('\U0001d6c2', '\U0001d6da'), ('\U0001d6db',
+ '\U0001d6db'), ('\U0001d6dc', '\U0001d6fa'), ('\U0001d6fb', '\U0001d6fb'), ('\U0001d6fc',
+ '\U0001d714'), ('\U0001d715', '\U0001d715'), ('\U0001d716', '\U0001d734'), ('\U0001d735',
+ '\U0001d735'), ('\U0001d736', '\U0001d74e'), ('\U0001d74f', '\U0001d74f'), ('\U0001d750',
+ '\U0001d76e'), ('\U0001d76f', '\U0001d76f'), ('\U0001d770', '\U0001d788'), ('\U0001d789',
+ '\U0001d789'), ('\U0001d78a', '\U0001d7a8'), ('\U0001d7a9', '\U0001d7a9'), ('\U0001d7aa',
+ '\U0001d7c2'), ('\U0001d7c3', '\U0001d7c3'), ('\U0001d7c4', '\U0001d7cb'), ('\U0001d7ce',
+ '\U0001d7ff'), ('\U0001f000', '\U0001f02b'), ('\U0001f030', '\U0001f093'), ('\U0001f0a0',
+ '\U0001f0ae'), ('\U0001f0b1', '\U0001f0bf'), ('\U0001f0c1', '\U0001f0cf'), ('\U0001f0d1',
+ '\U0001f0f5'), ('\U0001f100', '\U0001f10c'), ('\U0001f110', '\U0001f12e'), ('\U0001f130',
+ '\U0001f16b'), ('\U0001f170', '\U0001f19a'), ('\U0001f1e6', '\U0001f1ff'), ('\U0001f201',
+ '\U0001f202'), ('\U0001f210', '\U0001f23a'), ('\U0001f240', '\U0001f248'), ('\U0001f250',
+ '\U0001f251'), ('\U0001f300', '\U0001f32c'), ('\U0001f330', '\U0001f37d'), ('\U0001f380',
+ '\U0001f3ce'), ('\U0001f3d4', '\U0001f3f7'), ('\U0001f400', '\U0001f4fe'), ('\U0001f500',
+ '\U0001f54a'), ('\U0001f550', '\U0001f579'), ('\U0001f57b', '\U0001f5a3'), ('\U0001f5a5',
+ '\U0001f642'), ('\U0001f645', '\U0001f6cf'), ('\U0001f6e0', '\U0001f6ec'), ('\U0001f6f0',
+ '\U0001f6f3'), ('\U0001f700', '\U0001f773'), ('\U0001f780', '\U0001f7d4'), ('\U0001f800',
+ '\U0001f80b'), ('\U0001f810', '\U0001f847'), ('\U0001f850', '\U0001f859'), ('\U0001f860',
+ '\U0001f887'), ('\U0001f890', '\U0001f8ad'), ('\U000e0001', '\U000e0001'), ('\U000e0020',
+ '\U000e007f')
+ ];
+
+ pub static Coptic_table: &'static [(char, char)] = &[
+ ('\u03e2', '\u03ef'), ('\u2c80', '\u2ce4'), ('\u2ce5', '\u2cea'), ('\u2ceb', '\u2cee'),
+ ('\u2cef', '\u2cf1'), ('\u2cf2', '\u2cf3'), ('\u2cf9', '\u2cfc'), ('\u2cfd', '\u2cfd'),
+ ('\u2cfe', '\u2cff')
+ ];
+
+ pub static Cuneiform_table: &'static [(char, char)] = &[
+ ('\U00012000', '\U00012398'), ('\U00012400', '\U0001246e'), ('\U00012470', '\U00012474')
+ ];
+
+ pub static Cypriot_table: &'static [(char, char)] = &[
+ ('\U00010800', '\U00010805'), ('\U00010808', '\U00010808'), ('\U0001080a', '\U00010835'),
+ ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'), ('\U0001083f', '\U0001083f')
+ ];
+
+ pub static Cyrillic_table: &'static [(char, char)] = &[
+ ('\u0400', '\u0481'), ('\u0482', '\u0482'), ('\u0483', '\u0484'), ('\u0487', '\u0487'),
+ ('\u0488', '\u0489'), ('\u048a', '\u052f'), ('\u1d2b', '\u1d2b'), ('\u1d78', '\u1d78'),
+ ('\u2de0', '\u2dff'), ('\ua640', '\ua66d'), ('\ua66e', '\ua66e'), ('\ua66f', '\ua66f'),
+ ('\ua670', '\ua672'), ('\ua673', '\ua673'), ('\ua674', '\ua67d'), ('\ua67e', '\ua67e'),
+ ('\ua67f', '\ua67f'), ('\ua680', '\ua69b'), ('\ua69c', '\ua69d'), ('\ua69f', '\ua69f')
+ ];
+
+ pub static Deseret_table: &'static [(char, char)] = &[
+ ('\U00010400', '\U0001044f')
+ ];
+
+ pub static Devanagari_table: &'static [(char, char)] = &[
+ ('\u0900', '\u0902'), ('\u0903', '\u0903'), ('\u0904', '\u0939'), ('\u093a', '\u093a'),
+ ('\u093b', '\u093b'), ('\u093c', '\u093c'), ('\u093d', '\u093d'), ('\u093e', '\u0940'),
+ ('\u0941', '\u0948'), ('\u0949', '\u094c'), ('\u094d', '\u094d'), ('\u094e', '\u094f'),
+ ('\u0950', '\u0950'), ('\u0953', '\u0957'), ('\u0958', '\u0961'), ('\u0962', '\u0963'),
+ ('\u0966', '\u096f'), ('\u0970', '\u0970'), ('\u0971', '\u0971'), ('\u0972', '\u097f'),
+ ('\ua8e0', '\ua8f1'), ('\ua8f2', '\ua8f7'), ('\ua8f8', '\ua8fa'), ('\ua8fb', '\ua8fb')
+ ];
+
+ pub static Duployan_table: &'static [(char, char)] = &[
+ ('\U0001bc00', '\U0001bc6a'), ('\U0001bc70', '\U0001bc7c'), ('\U0001bc80', '\U0001bc88'),
+ ('\U0001bc90', '\U0001bc99'), ('\U0001bc9c', '\U0001bc9c'), ('\U0001bc9d', '\U0001bc9e'),
+ ('\U0001bc9f', '\U0001bc9f')
+ ];
+
+ pub static Egyptian_Hieroglyphs_table: &'static [(char, char)] = &[
+ ('\U00013000', '\U0001342e')
+ ];
+
+ pub static Elbasan_table: &'static [(char, char)] = &[
+ ('\U00010500', '\U00010527')
+ ];
+
+ pub static Ethiopic_table: &'static [(char, char)] = &[
+ ('\u1200', '\u1248'), ('\u124a', '\u124d'), ('\u1250', '\u1256'), ('\u1258', '\u1258'),
+ ('\u125a', '\u125d'), ('\u1260', '\u1288'), ('\u128a', '\u128d'), ('\u1290', '\u12b0'),
+ ('\u12b2', '\u12b5'), ('\u12b8', '\u12be'), ('\u12c0', '\u12c0'), ('\u12c2', '\u12c5'),
+ ('\u12c8', '\u12d6'), ('\u12d8', '\u1310'), ('\u1312', '\u1315'), ('\u1318', '\u135a'),
+ ('\u135d', '\u135f'), ('\u1360', '\u1368'), ('\u1369', '\u137c'), ('\u1380', '\u138f'),
+ ('\u1390', '\u1399'), ('\u2d80', '\u2d96'), ('\u2da0', '\u2da6'), ('\u2da8', '\u2dae'),
+ ('\u2db0', '\u2db6'), ('\u2db8', '\u2dbe'), ('\u2dc0', '\u2dc6'), ('\u2dc8', '\u2dce'),
+ ('\u2dd0', '\u2dd6'), ('\u2dd8', '\u2dde'), ('\uab01', '\uab06'), ('\uab09', '\uab0e'),
+ ('\uab11', '\uab16'), ('\uab20', '\uab26'), ('\uab28', '\uab2e')
+ ];
+
+ pub static Georgian_table: &'static [(char, char)] = &[
+ ('\u10a0', '\u10c5'), ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'), ('\u10d0', '\u10fa'),
+ ('\u10fc', '\u10fc'), ('\u10fd', '\u10ff'), ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'),
+ ('\u2d2d', '\u2d2d')
+ ];
+
+ pub static Glagolitic_table: &'static [(char, char)] = &[
+ ('\u2c00', '\u2c2e'), ('\u2c30', '\u2c5e')
+ ];
+
+ pub static Gothic_table: &'static [(char, char)] = &[
+ ('\U00010330', '\U00010340'), ('\U00010341', '\U00010341'), ('\U00010342', '\U00010349'),
+ ('\U0001034a', '\U0001034a')
+ ];
+
+ pub static Grantha_table: &'static [(char, char)] = &[
+ ('\U00011301', '\U00011301'), ('\U00011302', '\U00011303'), ('\U00011305', '\U0001130c'),
+ ('\U0001130f', '\U00011310'), ('\U00011313', '\U00011328'), ('\U0001132a', '\U00011330'),
+ ('\U00011332', '\U00011333'), ('\U00011335', '\U00011339'), ('\U0001133c', '\U0001133c'),
+ ('\U0001133d', '\U0001133d'), ('\U0001133e', '\U0001133f'), ('\U00011340', '\U00011340'),
+ ('\U00011341', '\U00011344'), ('\U00011347', '\U00011348'), ('\U0001134b', '\U0001134d'),
+ ('\U00011357', '\U00011357'), ('\U0001135d', '\U00011361'), ('\U00011362', '\U00011363'),
+ ('\U00011366', '\U0001136c'), ('\U00011370', '\U00011374')
+ ];
+
+ pub static Greek_table: &'static [(char, char)] = &[
+ ('\u0370', '\u0373'), ('\u0375', '\u0375'), ('\u0376', '\u0377'), ('\u037a', '\u037a'),
+ ('\u037b', '\u037d'), ('\u037f', '\u037f'), ('\u0384', '\u0384'), ('\u0386', '\u0386'),
+ ('\u0388', '\u038a'), ('\u038c', '\u038c'), ('\u038e', '\u03a1'), ('\u03a3', '\u03e1'),
+ ('\u03f0', '\u03f5'), ('\u03f6', '\u03f6'), ('\u03f7', '\u03ff'), ('\u1d26', '\u1d2a'),
+ ('\u1d5d', '\u1d61'), ('\u1d66', '\u1d6a'), ('\u1dbf', '\u1dbf'), ('\u1f00', '\u1f15'),
+ ('\u1f18', '\u1f1d'), ('\u1f20', '\u1f45'), ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'),
+ ('\u1f59', '\u1f59'), ('\u1f5b', '\u1f5b'), ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'),
+ ('\u1f80', '\u1fb4'), ('\u1fb6', '\u1fbc'), ('\u1fbd', '\u1fbd'), ('\u1fbe', '\u1fbe'),
+ ('\u1fbf', '\u1fc1'), ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fcc'), ('\u1fcd', '\u1fcf'),
+ ('\u1fd0', '\u1fd3'), ('\u1fd6', '\u1fdb'), ('\u1fdd', '\u1fdf'), ('\u1fe0', '\u1fec'),
+ ('\u1fed', '\u1fef'), ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ffc'), ('\u1ffd', '\u1ffe'),
+ ('\u2126', '\u2126'), ('\uab65', '\uab65'), ('\U00010140', '\U00010174'), ('\U00010175',
+ '\U00010178'), ('\U00010179', '\U00010189'), ('\U0001018a', '\U0001018b'), ('\U0001018c',
+ '\U0001018c'), ('\U000101a0', '\U000101a0'), ('\U0001d200', '\U0001d241'), ('\U0001d242',
+ '\U0001d244'), ('\U0001d245', '\U0001d245')
+ ];
+
+ pub static Gujarati_table: &'static [(char, char)] = &[
+ ('\u0a81', '\u0a82'), ('\u0a83', '\u0a83'), ('\u0a85', '\u0a8d'), ('\u0a8f', '\u0a91'),
+ ('\u0a93', '\u0aa8'), ('\u0aaa', '\u0ab0'), ('\u0ab2', '\u0ab3'), ('\u0ab5', '\u0ab9'),
+ ('\u0abc', '\u0abc'), ('\u0abd', '\u0abd'), ('\u0abe', '\u0ac0'), ('\u0ac1', '\u0ac5'),
+ ('\u0ac7', '\u0ac8'), ('\u0ac9', '\u0ac9'), ('\u0acb', '\u0acc'), ('\u0acd', '\u0acd'),
+ ('\u0ad0', '\u0ad0'), ('\u0ae0', '\u0ae1'), ('\u0ae2', '\u0ae3'), ('\u0ae6', '\u0aef'),
+ ('\u0af0', '\u0af0'), ('\u0af1', '\u0af1')
+ ];
+
+ pub static Gurmukhi_table: &'static [(char, char)] = &[
+ ('\u0a01', '\u0a02'), ('\u0a03', '\u0a03'), ('\u0a05', '\u0a0a'), ('\u0a0f', '\u0a10'),
+ ('\u0a13', '\u0a28'), ('\u0a2a', '\u0a30'), ('\u0a32', '\u0a33'), ('\u0a35', '\u0a36'),
+ ('\u0a38', '\u0a39'), ('\u0a3c', '\u0a3c'), ('\u0a3e', '\u0a40'), ('\u0a41', '\u0a42'),
+ ('\u0a47', '\u0a48'), ('\u0a4b', '\u0a4d'), ('\u0a51', '\u0a51'), ('\u0a59', '\u0a5c'),
+ ('\u0a5e', '\u0a5e'), ('\u0a66', '\u0a6f'), ('\u0a70', '\u0a71'), ('\u0a72', '\u0a74'),
+ ('\u0a75', '\u0a75')
+ ];
+
+ pub static Han_table: &'static [(char, char)] = &[
+ ('\u2e80', '\u2e99'), ('\u2e9b', '\u2ef3'), ('\u2f00', '\u2fd5'), ('\u3005', '\u3005'),
+ ('\u3007', '\u3007'), ('\u3021', '\u3029'), ('\u3038', '\u303a'), ('\u303b', '\u303b'),
+ ('\u3400', '\u4db5'), ('\u4e00', '\u9fcc'), ('\uf900', '\ufa6d'), ('\ufa70', '\ufad9'),
+ ('\U00020000', '\U0002a6d6'), ('\U0002a700', '\U0002b734'), ('\U0002b740', '\U0002b81d'),
+ ('\U0002f800', '\U0002fa1d')
+ ];
+
+ pub static Hangul_table: &'static [(char, char)] = &[
+ ('\u1100', '\u11ff'), ('\u302e', '\u302f'), ('\u3131', '\u318e'), ('\u3200', '\u321e'),
+ ('\u3260', '\u327e'), ('\ua960', '\ua97c'), ('\uac00', '\ud7a3'), ('\ud7b0', '\ud7c6'),
+ ('\ud7cb', '\ud7fb'), ('\uffa0', '\uffbe'), ('\uffc2', '\uffc7'), ('\uffca', '\uffcf'),
+ ('\uffd2', '\uffd7'), ('\uffda', '\uffdc')
+ ];
+
+ pub static Hanunoo_table: &'static [(char, char)] = &[
+ ('\u1720', '\u1731'), ('\u1732', '\u1734')
+ ];
+
+ pub static Hebrew_table: &'static [(char, char)] = &[
+ ('\u0591', '\u05bd'), ('\u05be', '\u05be'), ('\u05bf', '\u05bf'), ('\u05c0', '\u05c0'),
+ ('\u05c1', '\u05c2'), ('\u05c3', '\u05c3'), ('\u05c4', '\u05c5'), ('\u05c6', '\u05c6'),
+ ('\u05c7', '\u05c7'), ('\u05d0', '\u05ea'), ('\u05f0', '\u05f2'), ('\u05f3', '\u05f4'),
+ ('\ufb1d', '\ufb1d'), ('\ufb1e', '\ufb1e'), ('\ufb1f', '\ufb28'), ('\ufb29', '\ufb29'),
+ ('\ufb2a', '\ufb36'), ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'), ('\ufb40', '\ufb41'),
+ ('\ufb43', '\ufb44'), ('\ufb46', '\ufb4f')
+ ];
+
+ pub static Hiragana_table: &'static [(char, char)] = &[
+ ('\u3041', '\u3096'), ('\u309d', '\u309e'), ('\u309f', '\u309f'), ('\U0001b001',
+ '\U0001b001'), ('\U0001f200', '\U0001f200')
+ ];
+
+ pub static Imperial_Aramaic_table: &'static [(char, char)] = &[
+ ('\U00010840', '\U00010855'), ('\U00010857', '\U00010857'), ('\U00010858', '\U0001085f')
+ ];
+
+ pub static Inherited_table: &'static [(char, char)] = &[
+ ('\u0300', '\u036f'), ('\u0485', '\u0486'), ('\u064b', '\u0655'), ('\u0670', '\u0670'),
+ ('\u0951', '\u0952'), ('\u1ab0', '\u1abd'), ('\u1abe', '\u1abe'), ('\u1cd0', '\u1cd2'),
+ ('\u1cd4', '\u1ce0'), ('\u1ce2', '\u1ce8'), ('\u1ced', '\u1ced'), ('\u1cf4', '\u1cf4'),
+ ('\u1cf8', '\u1cf9'), ('\u1dc0', '\u1df5'), ('\u1dfc', '\u1dff'), ('\u200c', '\u200d'),
+ ('\u20d0', '\u20dc'), ('\u20dd', '\u20e0'), ('\u20e1', '\u20e1'), ('\u20e2', '\u20e4'),
+ ('\u20e5', '\u20f0'), ('\u302a', '\u302d'), ('\u3099', '\u309a'), ('\ufe00', '\ufe0f'),
+ ('\ufe20', '\ufe2d'), ('\U000101fd', '\U000101fd'), ('\U000102e0', '\U000102e0'),
+ ('\U0001d167', '\U0001d169'), ('\U0001d17b', '\U0001d182'), ('\U0001d185', '\U0001d18b'),
+ ('\U0001d1aa', '\U0001d1ad'), ('\U000e0100', '\U000e01ef')
+ ];
+
+ pub static Inscriptional_Pahlavi_table: &'static [(char, char)] = &[
+ ('\U00010b60', '\U00010b72'), ('\U00010b78', '\U00010b7f')
+ ];
+
+ pub static Inscriptional_Parthian_table: &'static [(char, char)] = &[
+ ('\U00010b40', '\U00010b55'), ('\U00010b58', '\U00010b5f')
+ ];
+
+ pub static Javanese_table: &'static [(char, char)] = &[
+ ('\ua980', '\ua982'), ('\ua983', '\ua983'), ('\ua984', '\ua9b2'), ('\ua9b3', '\ua9b3'),
+ ('\ua9b4', '\ua9b5'), ('\ua9b6', '\ua9b9'), ('\ua9ba', '\ua9bb'), ('\ua9bc', '\ua9bc'),
+ ('\ua9bd', '\ua9c0'), ('\ua9c1', '\ua9cd'), ('\ua9d0', '\ua9d9'), ('\ua9de', '\ua9df')
+ ];
+
+ pub static Kaithi_table: &'static [(char, char)] = &[
+ ('\U00011080', '\U00011081'), ('\U00011082', '\U00011082'), ('\U00011083', '\U000110af'),
+ ('\U000110b0', '\U000110b2'), ('\U000110b3', '\U000110b6'), ('\U000110b7', '\U000110b8'),
+ ('\U000110b9', '\U000110ba'), ('\U000110bb', '\U000110bc'), ('\U000110bd', '\U000110bd'),
+ ('\U000110be', '\U000110c1')
+ ];
+
+ pub static Kannada_table: &'static [(char, char)] = &[
+ ('\u0c81', '\u0c81'), ('\u0c82', '\u0c83'), ('\u0c85', '\u0c8c'), ('\u0c8e', '\u0c90'),
+ ('\u0c92', '\u0ca8'), ('\u0caa', '\u0cb3'), ('\u0cb5', '\u0cb9'), ('\u0cbc', '\u0cbc'),
+ ('\u0cbd', '\u0cbd'), ('\u0cbe', '\u0cbe'), ('\u0cbf', '\u0cbf'), ('\u0cc0', '\u0cc4'),
+ ('\u0cc6', '\u0cc6'), ('\u0cc7', '\u0cc8'), ('\u0cca', '\u0ccb'), ('\u0ccc', '\u0ccd'),
+ ('\u0cd5', '\u0cd6'), ('\u0cde', '\u0cde'), ('\u0ce0', '\u0ce1'), ('\u0ce2', '\u0ce3'),
+ ('\u0ce6', '\u0cef'), ('\u0cf1', '\u0cf2')
+ ];
+
+ pub static Katakana_table: &'static [(char, char)] = &[
+ ('\u30a1', '\u30fa'), ('\u30fd', '\u30fe'), ('\u30ff', '\u30ff'), ('\u31f0', '\u31ff'),
+ ('\u32d0', '\u32fe'), ('\u3300', '\u3357'), ('\uff66', '\uff6f'), ('\uff71', '\uff9d'),
+ ('\U0001b000', '\U0001b000')
+ ];
+
+ pub static Kayah_Li_table: &'static [(char, char)] = &[
+ ('\ua900', '\ua909'), ('\ua90a', '\ua925'), ('\ua926', '\ua92d'), ('\ua92f', '\ua92f')
+ ];
+
+ pub static Kharoshthi_table: &'static [(char, char)] = &[
+ ('\U00010a00', '\U00010a00'), ('\U00010a01', '\U00010a03'), ('\U00010a05', '\U00010a06'),
+ ('\U00010a0c', '\U00010a0f'), ('\U00010a10', '\U00010a13'), ('\U00010a15', '\U00010a17'),
+ ('\U00010a19', '\U00010a33'), ('\U00010a38', '\U00010a3a'), ('\U00010a3f', '\U00010a3f'),
+ ('\U00010a40', '\U00010a47'), ('\U00010a50', '\U00010a58')
+ ];
+
+ pub static Khmer_table: &'static [(char, char)] = &[
+ ('\u1780', '\u17b3'), ('\u17b4', '\u17b5'), ('\u17b6', '\u17b6'), ('\u17b7', '\u17bd'),
+ ('\u17be', '\u17c5'), ('\u17c6', '\u17c6'), ('\u17c7', '\u17c8'), ('\u17c9', '\u17d3'),
+ ('\u17d4', '\u17d6'), ('\u17d7', '\u17d7'), ('\u17d8', '\u17da'), ('\u17db', '\u17db'),
+ ('\u17dc', '\u17dc'), ('\u17dd', '\u17dd'), ('\u17e0', '\u17e9'), ('\u17f0', '\u17f9'),
+ ('\u19e0', '\u19ff')
+ ];
+
+ pub static Khojki_table: &'static [(char, char)] = &[
+ ('\U00011200', '\U00011211'), ('\U00011213', '\U0001122b'), ('\U0001122c', '\U0001122e'),
+ ('\U0001122f', '\U00011231'), ('\U00011232', '\U00011233'), ('\U00011234', '\U00011234'),
+ ('\U00011235', '\U00011235'), ('\U00011236', '\U00011237'), ('\U00011238', '\U0001123d')
+ ];
+
+ pub static Khudawadi_table: &'static [(char, char)] = &[
+ ('\U000112b0', '\U000112de'), ('\U000112df', '\U000112df'), ('\U000112e0', '\U000112e2'),
+ ('\U000112e3', '\U000112ea'), ('\U000112f0', '\U000112f9')
+ ];
+
+ pub static Lao_table: &'static [(char, char)] = &[
+ ('\u0e81', '\u0e82'), ('\u0e84', '\u0e84'), ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'),
+ ('\u0e8d', '\u0e8d'), ('\u0e94', '\u0e97'), ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'),
+ ('\u0ea5', '\u0ea5'), ('\u0ea7', '\u0ea7'), ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb0'),
+ ('\u0eb1', '\u0eb1'), ('\u0eb2', '\u0eb3'), ('\u0eb4', '\u0eb9'), ('\u0ebb', '\u0ebc'),
+ ('\u0ebd', '\u0ebd'), ('\u0ec0', '\u0ec4'), ('\u0ec6', '\u0ec6'), ('\u0ec8', '\u0ecd'),
+ ('\u0ed0', '\u0ed9'), ('\u0edc', '\u0edf')
+ ];
+
+ pub static Latin_table: &'static [(char, char)] = &[
+ ('\x41', '\x5a'), ('\x61', '\x7a'), ('\xaa', '\xaa'), ('\xba', '\xba'), ('\xc0', '\xd6'),
+ ('\xd8', '\xf6'), ('\xf8', '\u01ba'), ('\u01bb', '\u01bb'), ('\u01bc', '\u01bf'), ('\u01c0',
+ '\u01c3'), ('\u01c4', '\u0293'), ('\u0294', '\u0294'), ('\u0295', '\u02af'), ('\u02b0',
+ '\u02b8'), ('\u02e0', '\u02e4'), ('\u1d00', '\u1d25'), ('\u1d2c', '\u1d5c'), ('\u1d62',
+ '\u1d65'), ('\u1d6b', '\u1d77'), ('\u1d79', '\u1d9a'), ('\u1d9b', '\u1dbe'), ('\u1e00',
+ '\u1eff'), ('\u2071', '\u2071'), ('\u207f', '\u207f'), ('\u2090', '\u209c'), ('\u212a',
+ '\u212b'), ('\u2132', '\u2132'), ('\u214e', '\u214e'), ('\u2160', '\u2182'), ('\u2183',
+ '\u2184'), ('\u2185', '\u2188'), ('\u2c60', '\u2c7b'), ('\u2c7c', '\u2c7d'), ('\u2c7e',
+ '\u2c7f'), ('\ua722', '\ua76f'), ('\ua770', '\ua770'), ('\ua771', '\ua787'), ('\ua78b',
+ '\ua78e'), ('\ua790', '\ua7ad'), ('\ua7b0', '\ua7b1'), ('\ua7f7', '\ua7f7'), ('\ua7f8',
+ '\ua7f9'), ('\ua7fa', '\ua7fa'), ('\ua7fb', '\ua7ff'), ('\uab30', '\uab5a'), ('\uab5c',
+ '\uab5f'), ('\uab64', '\uab64'), ('\ufb00', '\ufb06'), ('\uff21', '\uff3a'), ('\uff41',
+ '\uff5a')
+ ];
+
+ pub static Lepcha_table: &'static [(char, char)] = &[
+ ('\u1c00', '\u1c23'), ('\u1c24', '\u1c2b'), ('\u1c2c', '\u1c33'), ('\u1c34', '\u1c35'),
+ ('\u1c36', '\u1c37'), ('\u1c3b', '\u1c3f'), ('\u1c40', '\u1c49'), ('\u1c4d', '\u1c4f')
+ ];
+
+ pub static Limbu_table: &'static [(char, char)] = &[
+ ('\u1900', '\u191e'), ('\u1920', '\u1922'), ('\u1923', '\u1926'), ('\u1927', '\u1928'),
+ ('\u1929', '\u192b'), ('\u1930', '\u1931'), ('\u1932', '\u1932'), ('\u1933', '\u1938'),
+ ('\u1939', '\u193b'), ('\u1940', '\u1940'), ('\u1944', '\u1945'), ('\u1946', '\u194f')
+ ];
+
+ pub static Linear_A_table: &'static [(char, char)] = &[
+ ('\U00010600', '\U00010736'), ('\U00010740', '\U00010755'), ('\U00010760', '\U00010767')
+ ];
+
+ pub static Linear_B_table: &'static [(char, char)] = &[
+ ('\U00010000', '\U0001000b'), ('\U0001000d', '\U00010026'), ('\U00010028', '\U0001003a'),
+ ('\U0001003c', '\U0001003d'), ('\U0001003f', '\U0001004d'), ('\U00010050', '\U0001005d'),
+ ('\U00010080', '\U000100fa')
+ ];
+
+ pub static Lisu_table: &'static [(char, char)] = &[
+ ('\ua4d0', '\ua4f7'), ('\ua4f8', '\ua4fd'), ('\ua4fe', '\ua4ff')
+ ];
+
+ pub static Lycian_table: &'static [(char, char)] = &[
+ ('\U00010280', '\U0001029c')
+ ];
+
+ pub static Lydian_table: &'static [(char, char)] = &[
+ ('\U00010920', '\U00010939'), ('\U0001093f', '\U0001093f')
+ ];
+
+ pub static Mahajani_table: &'static [(char, char)] = &[
+ ('\U00011150', '\U00011172'), ('\U00011173', '\U00011173'), ('\U00011174', '\U00011175'),
+ ('\U00011176', '\U00011176')
+ ];
+
+ pub static Malayalam_table: &'static [(char, char)] = &[
+ ('\u0d01', '\u0d01'), ('\u0d02', '\u0d03'), ('\u0d05', '\u0d0c'), ('\u0d0e', '\u0d10'),
+ ('\u0d12', '\u0d3a'), ('\u0d3d', '\u0d3d'), ('\u0d3e', '\u0d40'), ('\u0d41', '\u0d44'),
+ ('\u0d46', '\u0d48'), ('\u0d4a', '\u0d4c'), ('\u0d4d', '\u0d4d'), ('\u0d4e', '\u0d4e'),
+ ('\u0d57', '\u0d57'), ('\u0d60', '\u0d61'), ('\u0d62', '\u0d63'), ('\u0d66', '\u0d6f'),
+ ('\u0d70', '\u0d75'), ('\u0d79', '\u0d79'), ('\u0d7a', '\u0d7f')
+ ];
+
+ pub static Mandaic_table: &'static [(char, char)] = &[
+ ('\u0840', '\u0858'), ('\u0859', '\u085b'), ('\u085e', '\u085e')
+ ];
+
+ pub static Manichaean_table: &'static [(char, char)] = &[
+ ('\U00010ac0', '\U00010ac7'), ('\U00010ac8', '\U00010ac8'), ('\U00010ac9', '\U00010ae4'),
+ ('\U00010ae5', '\U00010ae6'), ('\U00010aeb', '\U00010aef'), ('\U00010af0', '\U00010af6')
+ ];
+
+ pub static Meetei_Mayek_table: &'static [(char, char)] = &[
+ ('\uaae0', '\uaaea'), ('\uaaeb', '\uaaeb'), ('\uaaec', '\uaaed'), ('\uaaee', '\uaaef'),
+ ('\uaaf0', '\uaaf1'), ('\uaaf2', '\uaaf2'), ('\uaaf3', '\uaaf4'), ('\uaaf5', '\uaaf5'),
+ ('\uaaf6', '\uaaf6'), ('\uabc0', '\uabe2'), ('\uabe3', '\uabe4'), ('\uabe5', '\uabe5'),
+ ('\uabe6', '\uabe7'), ('\uabe8', '\uabe8'), ('\uabe9', '\uabea'), ('\uabeb', '\uabeb'),
+ ('\uabec', '\uabec'), ('\uabed', '\uabed'), ('\uabf0', '\uabf9')
+ ];
+
+ pub static Mende_Kikakui_table: &'static [(char, char)] = &[
+ ('\U0001e800', '\U0001e8c4'), ('\U0001e8c7', '\U0001e8cf'), ('\U0001e8d0', '\U0001e8d6')
+ ];
+
+ pub static Meroitic_Cursive_table: &'static [(char, char)] = &[
+ ('\U000109a0', '\U000109b7'), ('\U000109be', '\U000109bf')
+ ];
+
+ pub static Meroitic_Hieroglyphs_table: &'static [(char, char)] = &[
+ ('\U00010980', '\U0001099f')
+ ];
+
+ pub static Miao_table: &'static [(char, char)] = &[
+ ('\U00016f00', '\U00016f44'), ('\U00016f50', '\U00016f50'), ('\U00016f51', '\U00016f7e'),
+ ('\U00016f8f', '\U00016f92'), ('\U00016f93', '\U00016f9f')
+ ];
+
+ pub static Modi_table: &'static [(char, char)] = &[
+ ('\U00011600', '\U0001162f'), ('\U00011630', '\U00011632'), ('\U00011633', '\U0001163a'),
+ ('\U0001163b', '\U0001163c'), ('\U0001163d', '\U0001163d'), ('\U0001163e', '\U0001163e'),
+ ('\U0001163f', '\U00011640'), ('\U00011641', '\U00011643'), ('\U00011644', '\U00011644'),
+ ('\U00011650', '\U00011659')
+ ];
+
+ pub static Mongolian_table: &'static [(char, char)] = &[
+ ('\u1800', '\u1801'), ('\u1804', '\u1804'), ('\u1806', '\u1806'), ('\u1807', '\u180a'),
+ ('\u180b', '\u180d'), ('\u180e', '\u180e'), ('\u1810', '\u1819'), ('\u1820', '\u1842'),
+ ('\u1843', '\u1843'), ('\u1844', '\u1877'), ('\u1880', '\u18a8'), ('\u18a9', '\u18a9'),
+ ('\u18aa', '\u18aa')
+ ];
+
+ pub static Mro_table: &'static [(char, char)] = &[
+ ('\U00016a40', '\U00016a5e'), ('\U00016a60', '\U00016a69'), ('\U00016a6e', '\U00016a6f')
+ ];
+
+ pub static Myanmar_table: &'static [(char, char)] = &[
+ ('\u1000', '\u102a'), ('\u102b', '\u102c'), ('\u102d', '\u1030'), ('\u1031', '\u1031'),
+ ('\u1032', '\u1037'), ('\u1038', '\u1038'), ('\u1039', '\u103a'), ('\u103b', '\u103c'),
+ ('\u103d', '\u103e'), ('\u103f', '\u103f'), ('\u1040', '\u1049'), ('\u104a', '\u104f'),
+ ('\u1050', '\u1055'), ('\u1056', '\u1057'), ('\u1058', '\u1059'), ('\u105a', '\u105d'),
+ ('\u105e', '\u1060'), ('\u1061', '\u1061'), ('\u1062', '\u1064'), ('\u1065', '\u1066'),
+ ('\u1067', '\u106d'), ('\u106e', '\u1070'), ('\u1071', '\u1074'), ('\u1075', '\u1081'),
+ ('\u1082', '\u1082'), ('\u1083', '\u1084'), ('\u1085', '\u1086'), ('\u1087', '\u108c'),
+ ('\u108d', '\u108d'), ('\u108e', '\u108e'), ('\u108f', '\u108f'), ('\u1090', '\u1099'),
+ ('\u109a', '\u109c'), ('\u109d', '\u109d'), ('\u109e', '\u109f'), ('\ua9e0', '\ua9e4'),
+ ('\ua9e5', '\ua9e5'), ('\ua9e6', '\ua9e6'), ('\ua9e7', '\ua9ef'), ('\ua9f0', '\ua9f9'),
+ ('\ua9fa', '\ua9fe'), ('\uaa60', '\uaa6f'), ('\uaa70', '\uaa70'), ('\uaa71', '\uaa76'),
+ ('\uaa77', '\uaa79'), ('\uaa7a', '\uaa7a'), ('\uaa7b', '\uaa7b'), ('\uaa7c', '\uaa7c'),
+ ('\uaa7d', '\uaa7d'), ('\uaa7e', '\uaa7f')
+ ];
+
+ pub static Nabataean_table: &'static [(char, char)] = &[
+ ('\U00010880', '\U0001089e'), ('\U000108a7', '\U000108af')
+ ];
+
+ pub static New_Tai_Lue_table: &'static [(char, char)] = &[
+ ('\u1980', '\u19ab'), ('\u19b0', '\u19c0'), ('\u19c1', '\u19c7'), ('\u19c8', '\u19c9'),
+ ('\u19d0', '\u19d9'), ('\u19da', '\u19da'), ('\u19de', '\u19df')
+ ];
+
+ pub static Nko_table: &'static [(char, char)] = &[
+ ('\u07c0', '\u07c9'), ('\u07ca', '\u07ea'), ('\u07eb', '\u07f3'), ('\u07f4', '\u07f5'),
+ ('\u07f6', '\u07f6'), ('\u07f7', '\u07f9'), ('\u07fa', '\u07fa')
+ ];
+
+ pub static Ogham_table: &'static [(char, char)] = &[
+ ('\u1680', '\u1680'), ('\u1681', '\u169a'), ('\u169b', '\u169b'), ('\u169c', '\u169c')
+ ];
+
+ pub static Ol_Chiki_table: &'static [(char, char)] = &[
+ ('\u1c50', '\u1c59'), ('\u1c5a', '\u1c77'), ('\u1c78', '\u1c7d'), ('\u1c7e', '\u1c7f')
+ ];
+
+ pub static Old_Italic_table: &'static [(char, char)] = &[
+ ('\U00010300', '\U0001031f'), ('\U00010320', '\U00010323')
+ ];
+
+ pub static Old_North_Arabian_table: &'static [(char, char)] = &[
+ ('\U00010a80', '\U00010a9c'), ('\U00010a9d', '\U00010a9f')
+ ];
+
+ pub static Old_Permic_table: &'static [(char, char)] = &[
+ ('\U00010350', '\U00010375'), ('\U00010376', '\U0001037a')
+ ];
+
+ pub static Old_Persian_table: &'static [(char, char)] = &[
+ ('\U000103a0', '\U000103c3'), ('\U000103c8', '\U000103cf'), ('\U000103d0', '\U000103d0'),
+ ('\U000103d1', '\U000103d5')
+ ];
+
+ pub static Old_South_Arabian_table: &'static [(char, char)] = &[
+ ('\U00010a60', '\U00010a7c'), ('\U00010a7d', '\U00010a7e'), ('\U00010a7f', '\U00010a7f')
+ ];
+
+ pub static Old_Turkic_table: &'static [(char, char)] = &[
+ ('\U00010c00', '\U00010c48')
+ ];
+
+ pub static Oriya_table: &'static [(char, char)] = &[
+ ('\u0b01', '\u0b01'), ('\u0b02', '\u0b03'), ('\u0b05', '\u0b0c'), ('\u0b0f', '\u0b10'),
+ ('\u0b13', '\u0b28'), ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'), ('\u0b35', '\u0b39'),
+ ('\u0b3c', '\u0b3c'), ('\u0b3d', '\u0b3d'), ('\u0b3e', '\u0b3e'), ('\u0b3f', '\u0b3f'),
+ ('\u0b40', '\u0b40'), ('\u0b41', '\u0b44'), ('\u0b47', '\u0b48'), ('\u0b4b', '\u0b4c'),
+ ('\u0b4d', '\u0b4d'), ('\u0b56', '\u0b56'), ('\u0b57', '\u0b57'), ('\u0b5c', '\u0b5d'),
+ ('\u0b5f', '\u0b61'), ('\u0b62', '\u0b63'), ('\u0b66', '\u0b6f'), ('\u0b70', '\u0b70'),
+ ('\u0b71', '\u0b71'), ('\u0b72', '\u0b77')
+ ];
+
+ pub static Osmanya_table: &'static [(char, char)] = &[
+ ('\U00010480', '\U0001049d'), ('\U000104a0', '\U000104a9')
+ ];
+
+ pub static Pahawh_Hmong_table: &'static [(char, char)] = &[
+ ('\U00016b00', '\U00016b2f'), ('\U00016b30', '\U00016b36'), ('\U00016b37', '\U00016b3b'),
+ ('\U00016b3c', '\U00016b3f'), ('\U00016b40', '\U00016b43'), ('\U00016b44', '\U00016b44'),
+ ('\U00016b45', '\U00016b45'), ('\U00016b50', '\U00016b59'), ('\U00016b5b', '\U00016b61'),
+ ('\U00016b63', '\U00016b77'), ('\U00016b7d', '\U00016b8f')
+ ];
+
+ pub static Palmyrene_table: &'static [(char, char)] = &[
+ ('\U00010860', '\U00010876'), ('\U00010877', '\U00010878'), ('\U00010879', '\U0001087f')
+ ];
+
+ pub static Pau_Cin_Hau_table: &'static [(char, char)] = &[
+ ('\U00011ac0', '\U00011af8')
+ ];
+
+ pub static Phags_Pa_table: &'static [(char, char)] = &[
+ ('\ua840', '\ua873'), ('\ua874', '\ua877')
+ ];
+
+ pub static Phoenician_table: &'static [(char, char)] = &[
+ ('\U00010900', '\U00010915'), ('\U00010916', '\U0001091b'), ('\U0001091f', '\U0001091f')
+ ];
+
+ pub static Psalter_Pahlavi_table: &'static [(char, char)] = &[
+ ('\U00010b80', '\U00010b91'), ('\U00010b99', '\U00010b9c'), ('\U00010ba9', '\U00010baf')
+ ];
+
+ pub static Rejang_table: &'static [(char, char)] = &[
+ ('\ua930', '\ua946'), ('\ua947', '\ua951'), ('\ua952', '\ua953'), ('\ua95f', '\ua95f')
+ ];
+
+ pub static Runic_table: &'static [(char, char)] = &[
+ ('\u16a0', '\u16ea'), ('\u16ee', '\u16f0'), ('\u16f1', '\u16f8')
+ ];
+
+ pub static Samaritan_table: &'static [(char, char)] = &[
+ ('\u0800', '\u0815'), ('\u0816', '\u0819'), ('\u081a', '\u081a'), ('\u081b', '\u0823'),
+ ('\u0824', '\u0824'), ('\u0825', '\u0827'), ('\u0828', '\u0828'), ('\u0829', '\u082d'),
+ ('\u0830', '\u083e')
+ ];
+
+ pub static Saurashtra_table: &'static [(char, char)] = &[
+ ('\ua880', '\ua881'), ('\ua882', '\ua8b3'), ('\ua8b4', '\ua8c3'), ('\ua8c4', '\ua8c4'),
+ ('\ua8ce', '\ua8cf'), ('\ua8d0', '\ua8d9')
+ ];
+
+ pub static Sharada_table: &'static [(char, char)] = &[
+ ('\U00011180', '\U00011181'), ('\U00011182', '\U00011182'), ('\U00011183', '\U000111b2'),
+ ('\U000111b3', '\U000111b5'), ('\U000111b6', '\U000111be'), ('\U000111bf', '\U000111c0'),
+ ('\U000111c1', '\U000111c4'), ('\U000111c5', '\U000111c8'), ('\U000111cd', '\U000111cd'),
+ ('\U000111d0', '\U000111d9'), ('\U000111da', '\U000111da')
+ ];
+
+ pub static Shavian_table: &'static [(char, char)] = &[
+ ('\U00010450', '\U0001047f')
+ ];
+
+ pub static Siddham_table: &'static [(char, char)] = &[
+ ('\U00011580', '\U000115ae'), ('\U000115af', '\U000115b1'), ('\U000115b2', '\U000115b5'),
+ ('\U000115b8', '\U000115bb'), ('\U000115bc', '\U000115bd'), ('\U000115be', '\U000115be'),
+ ('\U000115bf', '\U000115c0'), ('\U000115c1', '\U000115c9')
+ ];
+
+ pub static Sinhala_table: &'static [(char, char)] = &[
+ ('\u0d82', '\u0d83'), ('\u0d85', '\u0d96'), ('\u0d9a', '\u0db1'), ('\u0db3', '\u0dbb'),
+ ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'), ('\u0dca', '\u0dca'), ('\u0dcf', '\u0dd1'),
+ ('\u0dd2', '\u0dd4'), ('\u0dd6', '\u0dd6'), ('\u0dd8', '\u0ddf'), ('\u0de6', '\u0def'),
+ ('\u0df2', '\u0df3'), ('\u0df4', '\u0df4'), ('\U000111e1', '\U000111f4')
+ ];
+
+ pub static Sora_Sompeng_table: &'static [(char, char)] = &[
+ ('\U000110d0', '\U000110e8'), ('\U000110f0', '\U000110f9')
+ ];
+
+ pub static Sundanese_table: &'static [(char, char)] = &[
+ ('\u1b80', '\u1b81'), ('\u1b82', '\u1b82'), ('\u1b83', '\u1ba0'), ('\u1ba1', '\u1ba1'),
+ ('\u1ba2', '\u1ba5'), ('\u1ba6', '\u1ba7'), ('\u1ba8', '\u1ba9'), ('\u1baa', '\u1baa'),
+ ('\u1bab', '\u1bad'), ('\u1bae', '\u1baf'), ('\u1bb0', '\u1bb9'), ('\u1bba', '\u1bbf'),
+ ('\u1cc0', '\u1cc7')
+ ];
+
+ pub static Syloti_Nagri_table: &'static [(char, char)] = &[
+ ('\ua800', '\ua801'), ('\ua802', '\ua802'), ('\ua803', '\ua805'), ('\ua806', '\ua806'),
+ ('\ua807', '\ua80a'), ('\ua80b', '\ua80b'), ('\ua80c', '\ua822'), ('\ua823', '\ua824'),
+ ('\ua825', '\ua826'), ('\ua827', '\ua827'), ('\ua828', '\ua82b')
+ ];
+
+ pub static Syriac_table: &'static [(char, char)] = &[
+ ('\u0700', '\u070d'), ('\u070f', '\u070f'), ('\u0710', '\u0710'), ('\u0711', '\u0711'),
+ ('\u0712', '\u072f'), ('\u0730', '\u074a'), ('\u074d', '\u074f')
+ ];
+
+ pub static Tagalog_table: &'static [(char, char)] = &[
+ ('\u1700', '\u170c'), ('\u170e', '\u1711'), ('\u1712', '\u1714')
+ ];
+
+ pub static Tagbanwa_table: &'static [(char, char)] = &[
+ ('\u1760', '\u176c'), ('\u176e', '\u1770'), ('\u1772', '\u1773')
+ ];
+
+ pub static Tai_Le_table: &'static [(char, char)] = &[
+ ('\u1950', '\u196d'), ('\u1970', '\u1974')
+ ];
+
+ pub static Tai_Tham_table: &'static [(char, char)] = &[
+ ('\u1a20', '\u1a54'), ('\u1a55', '\u1a55'), ('\u1a56', '\u1a56'), ('\u1a57', '\u1a57'),
+ ('\u1a58', '\u1a5e'), ('\u1a60', '\u1a60'), ('\u1a61', '\u1a61'), ('\u1a62', '\u1a62'),
+ ('\u1a63', '\u1a64'), ('\u1a65', '\u1a6c'), ('\u1a6d', '\u1a72'), ('\u1a73', '\u1a7c'),
+ ('\u1a7f', '\u1a7f'), ('\u1a80', '\u1a89'), ('\u1a90', '\u1a99'), ('\u1aa0', '\u1aa6'),
+ ('\u1aa7', '\u1aa7'), ('\u1aa8', '\u1aad')
+ ];
+
+ pub static Tai_Viet_table: &'static [(char, char)] = &[
+ ('\uaa80', '\uaaaf'), ('\uaab0', '\uaab0'), ('\uaab1', '\uaab1'), ('\uaab2', '\uaab4'),
+ ('\uaab5', '\uaab6'), ('\uaab7', '\uaab8'), ('\uaab9', '\uaabd'), ('\uaabe', '\uaabf'),
+ ('\uaac0', '\uaac0'), ('\uaac1', '\uaac1'), ('\uaac2', '\uaac2'), ('\uaadb', '\uaadc'),
+ ('\uaadd', '\uaadd'), ('\uaade', '\uaadf')
+ ];
+
+ pub static Takri_table: &'static [(char, char)] = &[
+ ('\U00011680', '\U000116aa'), ('\U000116ab', '\U000116ab'), ('\U000116ac', '\U000116ac'),
+ ('\U000116ad', '\U000116ad'), ('\U000116ae', '\U000116af'), ('\U000116b0', '\U000116b5'),
+ ('\U000116b6', '\U000116b6'), ('\U000116b7', '\U000116b7'), ('\U000116c0', '\U000116c9')
+ ];
+
+ pub static Tamil_table: &'static [(char, char)] = &[
+ ('\u0b82', '\u0b82'), ('\u0b83', '\u0b83'), ('\u0b85', '\u0b8a'), ('\u0b8e', '\u0b90'),
+ ('\u0b92', '\u0b95'), ('\u0b99', '\u0b9a'), ('\u0b9c', '\u0b9c'), ('\u0b9e', '\u0b9f'),
+ ('\u0ba3', '\u0ba4'), ('\u0ba8', '\u0baa'), ('\u0bae', '\u0bb9'), ('\u0bbe', '\u0bbf'),
+ ('\u0bc0', '\u0bc0'), ('\u0bc1', '\u0bc2'), ('\u0bc6', '\u0bc8'), ('\u0bca', '\u0bcc'),
+ ('\u0bcd', '\u0bcd'), ('\u0bd0', '\u0bd0'), ('\u0bd7', '\u0bd7'), ('\u0be6', '\u0bef'),
+ ('\u0bf0', '\u0bf2'), ('\u0bf3', '\u0bf8'), ('\u0bf9', '\u0bf9'), ('\u0bfa', '\u0bfa')
+ ];
+
+ pub static Telugu_table: &'static [(char, char)] = &[
+ ('\u0c00', '\u0c00'), ('\u0c01', '\u0c03'), ('\u0c05', '\u0c0c'), ('\u0c0e', '\u0c10'),
+ ('\u0c12', '\u0c28'), ('\u0c2a', '\u0c39'), ('\u0c3d', '\u0c3d'), ('\u0c3e', '\u0c40'),
+ ('\u0c41', '\u0c44'), ('\u0c46', '\u0c48'), ('\u0c4a', '\u0c4d'), ('\u0c55', '\u0c56'),
+ ('\u0c58', '\u0c59'), ('\u0c60', '\u0c61'), ('\u0c62', '\u0c63'), ('\u0c66', '\u0c6f'),
+ ('\u0c78', '\u0c7e'), ('\u0c7f', '\u0c7f')
+ ];
+
+ pub static Thaana_table: &'static [(char, char)] = &[
+ ('\u0780', '\u07a5'), ('\u07a6', '\u07b0'), ('\u07b1', '\u07b1')
+ ];
+
+ pub static Thai_table: &'static [(char, char)] = &[
+ ('\u0e01', '\u0e30'), ('\u0e31', '\u0e31'), ('\u0e32', '\u0e33'), ('\u0e34', '\u0e3a'),
+ ('\u0e40', '\u0e45'), ('\u0e46', '\u0e46'), ('\u0e47', '\u0e4e'), ('\u0e4f', '\u0e4f'),
+ ('\u0e50', '\u0e59'), ('\u0e5a', '\u0e5b')
+ ];
+
+ pub static Tibetan_table: &'static [(char, char)] = &[
+ ('\u0f00', '\u0f00'), ('\u0f01', '\u0f03'), ('\u0f04', '\u0f12'), ('\u0f13', '\u0f13'),
+ ('\u0f14', '\u0f14'), ('\u0f15', '\u0f17'), ('\u0f18', '\u0f19'), ('\u0f1a', '\u0f1f'),
+ ('\u0f20', '\u0f29'), ('\u0f2a', '\u0f33'), ('\u0f34', '\u0f34'), ('\u0f35', '\u0f35'),
+ ('\u0f36', '\u0f36'), ('\u0f37', '\u0f37'), ('\u0f38', '\u0f38'), ('\u0f39', '\u0f39'),
+ ('\u0f3a', '\u0f3a'), ('\u0f3b', '\u0f3b'), ('\u0f3c', '\u0f3c'), ('\u0f3d', '\u0f3d'),
+ ('\u0f3e', '\u0f3f'), ('\u0f40', '\u0f47'), ('\u0f49', '\u0f6c'), ('\u0f71', '\u0f7e'),
+ ('\u0f7f', '\u0f7f'), ('\u0f80', '\u0f84'), ('\u0f85', '\u0f85'), ('\u0f86', '\u0f87'),
+ ('\u0f88', '\u0f8c'), ('\u0f8d', '\u0f97'), ('\u0f99', '\u0fbc'), ('\u0fbe', '\u0fc5'),
+ ('\u0fc6', '\u0fc6'), ('\u0fc7', '\u0fcc'), ('\u0fce', '\u0fcf'), ('\u0fd0', '\u0fd4'),
+ ('\u0fd9', '\u0fda')
+ ];
+
+ pub static Tifinagh_table: &'static [(char, char)] = &[
+ ('\u2d30', '\u2d67'), ('\u2d6f', '\u2d6f'), ('\u2d70', '\u2d70'), ('\u2d7f', '\u2d7f')
+ ];
+
+ pub static Tirhuta_table: &'static [(char, char)] = &[
+ ('\U00011480', '\U000114af'), ('\U000114b0', '\U000114b2'), ('\U000114b3', '\U000114b8'),
+ ('\U000114b9', '\U000114b9'), ('\U000114ba', '\U000114ba'), ('\U000114bb', '\U000114be'),
+ ('\U000114bf', '\U000114c0'), ('\U000114c1', '\U000114c1'), ('\U000114c2', '\U000114c3'),
+ ('\U000114c4', '\U000114c5'), ('\U000114c6', '\U000114c6'), ('\U000114c7', '\U000114c7'),
+ ('\U000114d0', '\U000114d9')
+ ];
+
+ pub static Ugaritic_table: &'static [(char, char)] = &[
+ ('\U00010380', '\U0001039d'), ('\U0001039f', '\U0001039f')
+ ];
+
+ pub static Vai_table: &'static [(char, char)] = &[
+ ('\ua500', '\ua60b'), ('\ua60c', '\ua60c'), ('\ua60d', '\ua60f'), ('\ua610', '\ua61f'),
+ ('\ua620', '\ua629'), ('\ua62a', '\ua62b')
+ ];
+
+ pub static Warang_Citi_table: &'static [(char, char)] = &[
+ ('\U000118a0', '\U000118df'), ('\U000118e0', '\U000118e9'), ('\U000118ea', '\U000118f2'),
+ ('\U000118ff', '\U000118ff')
+ ];
+
+ pub static Yi_table: &'static [(char, char)] = &[
+ ('\ua000', '\ua014'), ('\ua015', '\ua015'), ('\ua016', '\ua48c'), ('\ua490', '\ua4c6')
+ ];
+
+}
+
+pub mod property {
+ pub static Join_Control_table: &'static [(char, char)] = &[
+ ('\u200c', '\u200d')
+ ];
+
+ pub static White_Space_table: &'static [(char, char)] = &[
+ ('\x09', '\x0d'), ('\x20', '\x20'), ('\x85', '\x85'), ('\xa0', '\xa0'), ('\u1680',
+ '\u1680'), ('\u2000', '\u200a'), ('\u2028', '\u2028'), ('\u2029', '\u2029'), ('\u202f',
+ '\u202f'), ('\u205f', '\u205f'), ('\u3000', '\u3000')
+ ];
+
+ pub fn White_Space(c: char) -> bool {
+ super::bsearch_range_table(c, White_Space_table)
+ }
+
+}
+
+pub mod regex {
+ pub static UNICODE_CLASSES: &'static [(&'static str, &'static [(char, char)])] = &[
+ ("Alphabetic", super::derived_property::Alphabetic_table), ("Arabic",
+ super::script::Arabic_table), ("Armenian", super::script::Armenian_table), ("Avestan",
+ super::script::Avestan_table), ("Balinese", super::script::Balinese_table), ("Bamum",
+ super::script::Bamum_table), ("Bassa_Vah", super::script::Bassa_Vah_table), ("Batak",
+ super::script::Batak_table), ("Bengali", super::script::Bengali_table), ("Bopomofo",
+ super::script::Bopomofo_table), ("Brahmi", super::script::Brahmi_table), ("Braille",
+ super::script::Braille_table), ("Buginese", super::script::Buginese_table), ("Buhid",
+ super::script::Buhid_table), ("C", super::general_category::C_table),
+ ("Canadian_Aboriginal", super::script::Canadian_Aboriginal_table), ("Carian",
+ super::script::Carian_table), ("Caucasian_Albanian",
+ super::script::Caucasian_Albanian_table), ("Cc", super::general_category::Cc_table), ("Cf",
+ super::general_category::Cf_table), ("Chakma", super::script::Chakma_table), ("Cham",
+ super::script::Cham_table), ("Cherokee", super::script::Cherokee_table), ("Co",
+ super::general_category::Co_table), ("Common", super::script::Common_table), ("Coptic",
+ super::script::Coptic_table), ("Cuneiform", super::script::Cuneiform_table), ("Cypriot",
+ super::script::Cypriot_table), ("Cyrillic", super::script::Cyrillic_table), ("Deseret",
+ super::script::Deseret_table), ("Devanagari", super::script::Devanagari_table), ("Duployan",
+ super::script::Duployan_table), ("Egyptian_Hieroglyphs",
+ super::script::Egyptian_Hieroglyphs_table), ("Elbasan", super::script::Elbasan_table),
+ ("Ethiopic", super::script::Ethiopic_table), ("Georgian", super::script::Georgian_table),
+ ("Glagolitic", super::script::Glagolitic_table), ("Gothic", super::script::Gothic_table),
+ ("Grantha", super::script::Grantha_table), ("Greek", super::script::Greek_table),
+ ("Gujarati", super::script::Gujarati_table), ("Gurmukhi", super::script::Gurmukhi_table),
+ ("Han", super::script::Han_table), ("Hangul", super::script::Hangul_table), ("Hanunoo",
+ super::script::Hanunoo_table), ("Hebrew", super::script::Hebrew_table), ("Hiragana",
+ super::script::Hiragana_table), ("Imperial_Aramaic", super::script::Imperial_Aramaic_table),
+ ("Inherited", super::script::Inherited_table), ("Inscriptional_Pahlavi",
+ super::script::Inscriptional_Pahlavi_table), ("Inscriptional_Parthian",
+ super::script::Inscriptional_Parthian_table), ("Javanese", super::script::Javanese_table),
+ ("Join_Control", super::property::Join_Control_table), ("Kaithi",
+ super::script::Kaithi_table), ("Kannada", super::script::Kannada_table), ("Katakana",
+ super::script::Katakana_table), ("Kayah_Li", super::script::Kayah_Li_table), ("Kharoshthi",
+ super::script::Kharoshthi_table), ("Khmer", super::script::Khmer_table), ("Khojki",
+ super::script::Khojki_table), ("Khudawadi", super::script::Khudawadi_table), ("L",
+ super::general_category::L_table), ("LC", super::general_category::LC_table), ("Lao",
+ super::script::Lao_table), ("Latin", super::script::Latin_table), ("Lepcha",
+ super::script::Lepcha_table), ("Limbu", super::script::Limbu_table), ("Linear_A",
+ super::script::Linear_A_table), ("Linear_B", super::script::Linear_B_table), ("Lisu",
+ super::script::Lisu_table), ("Ll", super::general_category::Ll_table), ("Lm",
+ super::general_category::Lm_table), ("Lo", super::general_category::Lo_table), ("Lowercase",
+ super::derived_property::Lowercase_table), ("Lt", super::general_category::Lt_table), ("Lu",
+ super::general_category::Lu_table), ("Lycian", super::script::Lycian_table), ("Lydian",
+ super::script::Lydian_table), ("M", super::general_category::M_table), ("Mahajani",
+ super::script::Mahajani_table), ("Malayalam", super::script::Malayalam_table), ("Mandaic",
+ super::script::Mandaic_table), ("Manichaean", super::script::Manichaean_table), ("Mc",
+ super::general_category::Mc_table), ("Me", super::general_category::Me_table),
+ ("Meetei_Mayek", super::script::Meetei_Mayek_table), ("Mende_Kikakui",
+ super::script::Mende_Kikakui_table), ("Meroitic_Cursive",
+ super::script::Meroitic_Cursive_table), ("Meroitic_Hieroglyphs",
+ super::script::Meroitic_Hieroglyphs_table), ("Miao", super::script::Miao_table), ("Mn",
+ super::general_category::Mn_table), ("Modi", super::script::Modi_table), ("Mongolian",
+ super::script::Mongolian_table), ("Mro", super::script::Mro_table), ("Myanmar",
+ super::script::Myanmar_table), ("N", super::general_category::N_table), ("Nabataean",
+ super::script::Nabataean_table), ("Nd", super::general_category::Nd_table), ("New_Tai_Lue",
+ super::script::New_Tai_Lue_table), ("Nko", super::script::Nko_table), ("Nl",
+ super::general_category::Nl_table), ("No", super::general_category::No_table), ("Ogham",
+ super::script::Ogham_table), ("Ol_Chiki", super::script::Ol_Chiki_table), ("Old_Italic",
+ super::script::Old_Italic_table), ("Old_North_Arabian",
+ super::script::Old_North_Arabian_table), ("Old_Permic", super::script::Old_Permic_table),
+ ("Old_Persian", super::script::Old_Persian_table), ("Old_South_Arabian",
+ super::script::Old_South_Arabian_table), ("Old_Turkic", super::script::Old_Turkic_table),
+ ("Oriya", super::script::Oriya_table), ("Osmanya", super::script::Osmanya_table), ("P",
+ super::general_category::P_table), ("Pahawh_Hmong", super::script::Pahawh_Hmong_table),
+ ("Palmyrene", super::script::Palmyrene_table), ("Pau_Cin_Hau",
+ super::script::Pau_Cin_Hau_table), ("Pc", super::general_category::Pc_table), ("Pd",
+ super::general_category::Pd_table), ("Pe", super::general_category::Pe_table), ("Pf",
+ super::general_category::Pf_table), ("Phags_Pa", super::script::Phags_Pa_table),
+ ("Phoenician", super::script::Phoenician_table), ("Pi", super::general_category::Pi_table),
+ ("Po", super::general_category::Po_table), ("Ps", super::general_category::Ps_table),
+ ("Psalter_Pahlavi", super::script::Psalter_Pahlavi_table), ("Rejang",
+ super::script::Rejang_table), ("Runic", super::script::Runic_table), ("S",
+ super::general_category::S_table), ("Samaritan", super::script::Samaritan_table),
+ ("Saurashtra", super::script::Saurashtra_table), ("Sc", super::general_category::Sc_table),
+ ("Sharada", super::script::Sharada_table), ("Shavian", super::script::Shavian_table),
+ ("Siddham", super::script::Siddham_table), ("Sinhala", super::script::Sinhala_table), ("Sk",
+ super::general_category::Sk_table), ("Sm", super::general_category::Sm_table), ("So",
+ super::general_category::So_table), ("Sora_Sompeng", super::script::Sora_Sompeng_table),
+ ("Sundanese", super::script::Sundanese_table), ("Syloti_Nagri",
+ super::script::Syloti_Nagri_table), ("Syriac", super::script::Syriac_table), ("Tagalog",
+ super::script::Tagalog_table), ("Tagbanwa", super::script::Tagbanwa_table), ("Tai_Le",
+ super::script::Tai_Le_table), ("Tai_Tham", super::script::Tai_Tham_table), ("Tai_Viet",
+ super::script::Tai_Viet_table), ("Takri", super::script::Takri_table), ("Tamil",
+ super::script::Tamil_table), ("Telugu", super::script::Telugu_table), ("Thaana",
+ super::script::Thaana_table), ("Thai", super::script::Thai_table), ("Tibetan",
+ super::script::Tibetan_table), ("Tifinagh", super::script::Tifinagh_table), ("Tirhuta",
+ super::script::Tirhuta_table), ("Ugaritic", super::script::Ugaritic_table), ("Uppercase",
+ super::derived_property::Uppercase_table), ("Vai", super::script::Vai_table),
+ ("Warang_Citi", super::script::Warang_Citi_table), ("White_Space",
+ super::property::White_Space_table), ("XID_Continue",
+ super::derived_property::XID_Continue_table), ("XID_Start",
+ super::derived_property::XID_Start_table), ("Yi", super::script::Yi_table), ("Z",
+ super::general_category::Z_table), ("Zl", super::general_category::Zl_table), ("Zp",
+ super::general_category::Zp_table), ("Zs", super::general_category::Zs_table)
+ ];
+
+ pub static PERLD: &'static [(char, char)] = super::general_category::Nd_table;
+
+ pub static PERLS: &'static [(char, char)] = super::property::White_Space_table;
+
+ pub static PERLW: &'static [(char, char)] = &[
+ ('\x30', '\x39'), ('\x41', '\x5a'), ('\x5f', '\x5f'), ('\x61', '\x7a'), ('\xaa', '\xaa'),
+ ('\xb5', '\xb5'), ('\xba', '\xba'), ('\xc0', '\xd6'), ('\xd8', '\xf6'), ('\xf8', '\u02c1'),
+ ('\u02c6', '\u02d1'), ('\u02e0', '\u02e4'), ('\u02ec', '\u02ec'), ('\u02ee', '\u02ee'),
+ ('\u0300', '\u0374'), ('\u0376', '\u0377'), ('\u037a', '\u037d'), ('\u037f', '\u037f'),
+ ('\u0386', '\u0386'), ('\u0388', '\u038a'), ('\u038c', '\u038c'), ('\u038e', '\u03a1'),
+ ('\u03a3', '\u03f5'), ('\u03f7', '\u0481'), ('\u0483', '\u052f'), ('\u0531', '\u0556'),
+ ('\u0559', '\u0559'), ('\u0561', '\u0587'), ('\u0591', '\u05bd'), ('\u05bf', '\u05bf'),
+ ('\u05c1', '\u05c2'), ('\u05c4', '\u05c5'), ('\u05c7', '\u05c7'), ('\u05d0', '\u05ea'),
+ ('\u05f0', '\u05f2'), ('\u0610', '\u061a'), ('\u0620', '\u0669'), ('\u066e', '\u06d3'),
+ ('\u06d5', '\u06dc'), ('\u06df', '\u06e8'), ('\u06ea', '\u06fc'), ('\u06ff', '\u06ff'),
+ ('\u0710', '\u074a'), ('\u074d', '\u07b1'), ('\u07c0', '\u07f5'), ('\u07fa', '\u07fa'),
+ ('\u0800', '\u082d'), ('\u0840', '\u085b'), ('\u08a0', '\u08b2'), ('\u08e4', '\u0963'),
+ ('\u0966', '\u096f'), ('\u0971', '\u0983'), ('\u0985', '\u098c'), ('\u098f', '\u0990'),
+ ('\u0993', '\u09a8'), ('\u09aa', '\u09b0'), ('\u09b2', '\u09b2'), ('\u09b6', '\u09b9'),
+ ('\u09bc', '\u09c4'), ('\u09c7', '\u09c8'), ('\u09cb', '\u09ce'), ('\u09d7', '\u09d7'),
+ ('\u09dc', '\u09dd'), ('\u09df', '\u09e3'), ('\u09e6', '\u09f1'), ('\u0a01', '\u0a03'),
+ ('\u0a05', '\u0a0a'), ('\u0a0f', '\u0a10'), ('\u0a13', '\u0a28'), ('\u0a2a', '\u0a30'),
+ ('\u0a32', '\u0a33'), ('\u0a35', '\u0a36'), ('\u0a38', '\u0a39'), ('\u0a3c', '\u0a3c'),
+ ('\u0a3e', '\u0a42'), ('\u0a47', '\u0a48'), ('\u0a4b', '\u0a4d'), ('\u0a51', '\u0a51'),
+ ('\u0a59', '\u0a5c'), ('\u0a5e', '\u0a5e'), ('\u0a66', '\u0a75'), ('\u0a81', '\u0a83'),
+ ('\u0a85', '\u0a8d'), ('\u0a8f', '\u0a91'), ('\u0a93', '\u0aa8'), ('\u0aaa', '\u0ab0'),
+ ('\u0ab2', '\u0ab3'), ('\u0ab5', '\u0ab9'), ('\u0abc', '\u0ac5'), ('\u0ac7', '\u0ac9'),
+ ('\u0acb', '\u0acd'), ('\u0ad0', '\u0ad0'), ('\u0ae0', '\u0ae3'), ('\u0ae6', '\u0aef'),
+ ('\u0b01', '\u0b03'), ('\u0b05', '\u0b0c'), ('\u0b0f', '\u0b10'), ('\u0b13', '\u0b28'),
+ ('\u0b2a', '\u0b30'), ('\u0b32', '\u0b33'), ('\u0b35', '\u0b39'), ('\u0b3c', '\u0b44'),
+ ('\u0b47', '\u0b48'), ('\u0b4b', '\u0b4d'), ('\u0b56', '\u0b57'), ('\u0b5c', '\u0b5d'),
+ ('\u0b5f', '\u0b63'), ('\u0b66', '\u0b6f'), ('\u0b71', '\u0b71'), ('\u0b82', '\u0b83'),
+ ('\u0b85', '\u0b8a'), ('\u0b8e', '\u0b90'), ('\u0b92', '\u0b95'), ('\u0b99', '\u0b9a'),
+ ('\u0b9c', '\u0b9c'), ('\u0b9e', '\u0b9f'), ('\u0ba3', '\u0ba4'), ('\u0ba8', '\u0baa'),
+ ('\u0bae', '\u0bb9'), ('\u0bbe', '\u0bc2'), ('\u0bc6', '\u0bc8'), ('\u0bca', '\u0bcd'),
+ ('\u0bd0', '\u0bd0'), ('\u0bd7', '\u0bd7'), ('\u0be6', '\u0bef'), ('\u0c00', '\u0c03'),
+ ('\u0c05', '\u0c0c'), ('\u0c0e', '\u0c10'), ('\u0c12', '\u0c28'), ('\u0c2a', '\u0c39'),
+ ('\u0c3d', '\u0c44'), ('\u0c46', '\u0c48'), ('\u0c4a', '\u0c4d'), ('\u0c55', '\u0c56'),
+ ('\u0c58', '\u0c59'), ('\u0c60', '\u0c63'), ('\u0c66', '\u0c6f'), ('\u0c81', '\u0c83'),
+ ('\u0c85', '\u0c8c'), ('\u0c8e', '\u0c90'), ('\u0c92', '\u0ca8'), ('\u0caa', '\u0cb3'),
+ ('\u0cb5', '\u0cb9'), ('\u0cbc', '\u0cc4'), ('\u0cc6', '\u0cc8'), ('\u0cca', '\u0ccd'),
+ ('\u0cd5', '\u0cd6'), ('\u0cde', '\u0cde'), ('\u0ce0', '\u0ce3'), ('\u0ce6', '\u0cef'),
+ ('\u0cf1', '\u0cf2'), ('\u0d01', '\u0d03'), ('\u0d05', '\u0d0c'), ('\u0d0e', '\u0d10'),
+ ('\u0d12', '\u0d3a'), ('\u0d3d', '\u0d44'), ('\u0d46', '\u0d48'), ('\u0d4a', '\u0d4e'),
+ ('\u0d57', '\u0d57'), ('\u0d60', '\u0d63'), ('\u0d66', '\u0d6f'), ('\u0d7a', '\u0d7f'),
+ ('\u0d82', '\u0d83'), ('\u0d85', '\u0d96'), ('\u0d9a', '\u0db1'), ('\u0db3', '\u0dbb'),
+ ('\u0dbd', '\u0dbd'), ('\u0dc0', '\u0dc6'), ('\u0dca', '\u0dca'), ('\u0dcf', '\u0dd4'),
+ ('\u0dd6', '\u0dd6'), ('\u0dd8', '\u0ddf'), ('\u0de6', '\u0def'), ('\u0df2', '\u0df3'),
+ ('\u0e01', '\u0e3a'), ('\u0e40', '\u0e4e'), ('\u0e50', '\u0e59'), ('\u0e81', '\u0e82'),
+ ('\u0e84', '\u0e84'), ('\u0e87', '\u0e88'), ('\u0e8a', '\u0e8a'), ('\u0e8d', '\u0e8d'),
+ ('\u0e94', '\u0e97'), ('\u0e99', '\u0e9f'), ('\u0ea1', '\u0ea3'), ('\u0ea5', '\u0ea5'),
+ ('\u0ea7', '\u0ea7'), ('\u0eaa', '\u0eab'), ('\u0ead', '\u0eb9'), ('\u0ebb', '\u0ebd'),
+ ('\u0ec0', '\u0ec4'), ('\u0ec6', '\u0ec6'), ('\u0ec8', '\u0ecd'), ('\u0ed0', '\u0ed9'),
+ ('\u0edc', '\u0edf'), ('\u0f00', '\u0f00'), ('\u0f18', '\u0f19'), ('\u0f20', '\u0f29'),
+ ('\u0f35', '\u0f35'), ('\u0f37', '\u0f37'), ('\u0f39', '\u0f39'), ('\u0f3e', '\u0f47'),
+ ('\u0f49', '\u0f6c'), ('\u0f71', '\u0f84'), ('\u0f86', '\u0f97'), ('\u0f99', '\u0fbc'),
+ ('\u0fc6', '\u0fc6'), ('\u1000', '\u1049'), ('\u1050', '\u109d'), ('\u10a0', '\u10c5'),
+ ('\u10c7', '\u10c7'), ('\u10cd', '\u10cd'), ('\u10d0', '\u10fa'), ('\u10fc', '\u1248'),
+ ('\u124a', '\u124d'), ('\u1250', '\u1256'), ('\u1258', '\u1258'), ('\u125a', '\u125d'),
+ ('\u1260', '\u1288'), ('\u128a', '\u128d'), ('\u1290', '\u12b0'), ('\u12b2', '\u12b5'),
+ ('\u12b8', '\u12be'), ('\u12c0', '\u12c0'), ('\u12c2', '\u12c5'), ('\u12c8', '\u12d6'),
+ ('\u12d8', '\u1310'), ('\u1312', '\u1315'), ('\u1318', '\u135a'), ('\u135d', '\u135f'),
+ ('\u1380', '\u138f'), ('\u13a0', '\u13f4'), ('\u1401', '\u166c'), ('\u166f', '\u167f'),
+ ('\u1681', '\u169a'), ('\u16a0', '\u16ea'), ('\u16ee', '\u16f8'), ('\u1700', '\u170c'),
+ ('\u170e', '\u1714'), ('\u1720', '\u1734'), ('\u1740', '\u1753'), ('\u1760', '\u176c'),
+ ('\u176e', '\u1770'), ('\u1772', '\u1773'), ('\u1780', '\u17d3'), ('\u17d7', '\u17d7'),
+ ('\u17dc', '\u17dd'), ('\u17e0', '\u17e9'), ('\u180b', '\u180d'), ('\u1810', '\u1819'),
+ ('\u1820', '\u1877'), ('\u1880', '\u18aa'), ('\u18b0', '\u18f5'), ('\u1900', '\u191e'),
+ ('\u1920', '\u192b'), ('\u1930', '\u193b'), ('\u1946', '\u196d'), ('\u1970', '\u1974'),
+ ('\u1980', '\u19ab'), ('\u19b0', '\u19c9'), ('\u19d0', '\u19d9'), ('\u1a00', '\u1a1b'),
+ ('\u1a20', '\u1a5e'), ('\u1a60', '\u1a7c'), ('\u1a7f', '\u1a89'), ('\u1a90', '\u1a99'),
+ ('\u1aa7', '\u1aa7'), ('\u1ab0', '\u1abe'), ('\u1b00', '\u1b4b'), ('\u1b50', '\u1b59'),
+ ('\u1b6b', '\u1b73'), ('\u1b80', '\u1bf3'), ('\u1c00', '\u1c37'), ('\u1c40', '\u1c49'),
+ ('\u1c4d', '\u1c7d'), ('\u1cd0', '\u1cd2'), ('\u1cd4', '\u1cf6'), ('\u1cf8', '\u1cf9'),
+ ('\u1d00', '\u1df5'), ('\u1dfc', '\u1f15'), ('\u1f18', '\u1f1d'), ('\u1f20', '\u1f45'),
+ ('\u1f48', '\u1f4d'), ('\u1f50', '\u1f57'), ('\u1f59', '\u1f59'), ('\u1f5b', '\u1f5b'),
+ ('\u1f5d', '\u1f5d'), ('\u1f5f', '\u1f7d'), ('\u1f80', '\u1fb4'), ('\u1fb6', '\u1fbc'),
+ ('\u1fbe', '\u1fbe'), ('\u1fc2', '\u1fc4'), ('\u1fc6', '\u1fcc'), ('\u1fd0', '\u1fd3'),
+ ('\u1fd6', '\u1fdb'), ('\u1fe0', '\u1fec'), ('\u1ff2', '\u1ff4'), ('\u1ff6', '\u1ffc'),
+ ('\u200c', '\u200d'), ('\u203f', '\u2040'), ('\u2054', '\u2054'), ('\u2071', '\u2071'),
+ ('\u207f', '\u207f'), ('\u2090', '\u209c'), ('\u20d0', '\u20f0'), ('\u2102', '\u2102'),
+ ('\u2107', '\u2107'), ('\u210a', '\u2113'), ('\u2115', '\u2115'), ('\u2119', '\u211d'),
+ ('\u2124', '\u2124'), ('\u2126', '\u2126'), ('\u2128', '\u2128'), ('\u212a', '\u212d'),
+ ('\u212f', '\u2139'), ('\u213c', '\u213f'), ('\u2145', '\u2149'), ('\u214e', '\u214e'),
+ ('\u2160', '\u2188'), ('\u24b6', '\u24e9'), ('\u2c00', '\u2c2e'), ('\u2c30', '\u2c5e'),
+ ('\u2c60', '\u2ce4'), ('\u2ceb', '\u2cf3'), ('\u2d00', '\u2d25'), ('\u2d27', '\u2d27'),
+ ('\u2d2d', '\u2d2d'), ('\u2d30', '\u2d67'), ('\u2d6f', '\u2d6f'), ('\u2d7f', '\u2d96'),
+ ('\u2da0', '\u2da6'), ('\u2da8', '\u2dae'), ('\u2db0', '\u2db6'), ('\u2db8', '\u2dbe'),
+ ('\u2dc0', '\u2dc6'), ('\u2dc8', '\u2dce'), ('\u2dd0', '\u2dd6'), ('\u2dd8', '\u2dde'),
+ ('\u2de0', '\u2dff'), ('\u2e2f', '\u2e2f'), ('\u3005', '\u3007'), ('\u3021', '\u302f'),
+ ('\u3031', '\u3035'), ('\u3038', '\u303c'), ('\u3041', '\u3096'), ('\u3099', '\u309a'),
+ ('\u309d', '\u309f'), ('\u30a1', '\u30fa'), ('\u30fc', '\u30ff'), ('\u3105', '\u312d'),
+ ('\u3131', '\u318e'), ('\u31a0', '\u31ba'), ('\u31f0', '\u31ff'), ('\u3400', '\u4db5'),
+ ('\u4e00', '\u9fcc'), ('\ua000', '\ua48c'), ('\ua4d0', '\ua4fd'), ('\ua500', '\ua60c'),
+ ('\ua610', '\ua62b'), ('\ua640', '\ua672'), ('\ua674', '\ua67d'), ('\ua67f', '\ua69d'),
+ ('\ua69f', '\ua6f1'), ('\ua717', '\ua71f'), ('\ua722', '\ua788'), ('\ua78b', '\ua78e'),
+ ('\ua790', '\ua7ad'), ('\ua7b0', '\ua7b1'), ('\ua7f7', '\ua827'), ('\ua840', '\ua873'),
+ ('\ua880', '\ua8c4'), ('\ua8d0', '\ua8d9'), ('\ua8e0', '\ua8f7'), ('\ua8fb', '\ua8fb'),
+ ('\ua900', '\ua92d'), ('\ua930', '\ua953'), ('\ua960', '\ua97c'), ('\ua980', '\ua9c0'),
+ ('\ua9cf', '\ua9d9'), ('\ua9e0', '\ua9fe'), ('\uaa00', '\uaa36'), ('\uaa40', '\uaa4d'),
+ ('\uaa50', '\uaa59'), ('\uaa60', '\uaa76'), ('\uaa7a', '\uaac2'), ('\uaadb', '\uaadd'),
+ ('\uaae0', '\uaaef'), ('\uaaf2', '\uaaf6'), ('\uab01', '\uab06'), ('\uab09', '\uab0e'),
+ ('\uab11', '\uab16'), ('\uab20', '\uab26'), ('\uab28', '\uab2e'), ('\uab30', '\uab5a'),
+ ('\uab5c', '\uab5f'), ('\uab64', '\uab65'), ('\uabc0', '\uabea'), ('\uabec', '\uabed'),
+ ('\uabf0', '\uabf9'), ('\uac00', '\ud7a3'), ('\ud7b0', '\ud7c6'), ('\ud7cb', '\ud7fb'),
+ ('\uf900', '\ufa6d'), ('\ufa70', '\ufad9'), ('\ufb00', '\ufb06'), ('\ufb13', '\ufb17'),
+ ('\ufb1d', '\ufb28'), ('\ufb2a', '\ufb36'), ('\ufb38', '\ufb3c'), ('\ufb3e', '\ufb3e'),
+ ('\ufb40', '\ufb41'), ('\ufb43', '\ufb44'), ('\ufb46', '\ufbb1'), ('\ufbd3', '\ufd3d'),
+ ('\ufd50', '\ufd8f'), ('\ufd92', '\ufdc7'), ('\ufdf0', '\ufdfb'), ('\ufe00', '\ufe0f'),
+ ('\ufe20', '\ufe2d'), ('\ufe33', '\ufe34'), ('\ufe4d', '\ufe4f'), ('\ufe70', '\ufe74'),
+ ('\ufe76', '\ufefc'), ('\uff10', '\uff19'), ('\uff21', '\uff3a'), ('\uff3f', '\uff3f'),
+ ('\uff41', '\uff5a'), ('\uff66', '\uffbe'), ('\uffc2', '\uffc7'), ('\uffca', '\uffcf'),
+ ('\uffd2', '\uffd7'), ('\uffda', '\uffdc'), ('\U00010000', '\U0001000b'), ('\U0001000d',
+ '\U00010026'), ('\U00010028', '\U0001003a'), ('\U0001003c', '\U0001003d'), ('\U0001003f',
+ '\U0001004d'), ('\U00010050', '\U0001005d'), ('\U00010080', '\U000100fa'), ('\U00010140',
+ '\U00010174'), ('\U000101fd', '\U000101fd'), ('\U00010280', '\U0001029c'), ('\U000102a0',
+ '\U000102d0'), ('\U000102e0', '\U000102e0'), ('\U00010300', '\U0001031f'), ('\U00010330',
+ '\U0001034a'), ('\U00010350', '\U0001037a'), ('\U00010380', '\U0001039d'), ('\U000103a0',
+ '\U000103c3'), ('\U000103c8', '\U000103cf'), ('\U000103d1', '\U000103d5'), ('\U00010400',
+ '\U0001049d'), ('\U000104a0', '\U000104a9'), ('\U00010500', '\U00010527'), ('\U00010530',
+ '\U00010563'), ('\U00010600', '\U00010736'), ('\U00010740', '\U00010755'), ('\U00010760',
+ '\U00010767'), ('\U00010800', '\U00010805'), ('\U00010808', '\U00010808'), ('\U0001080a',
+ '\U00010835'), ('\U00010837', '\U00010838'), ('\U0001083c', '\U0001083c'), ('\U0001083f',
+ '\U00010855'), ('\U00010860', '\U00010876'), ('\U00010880', '\U0001089e'), ('\U00010900',
+ '\U00010915'), ('\U00010920', '\U00010939'), ('\U00010980', '\U000109b7'), ('\U000109be',
+ '\U000109bf'), ('\U00010a00', '\U00010a03'), ('\U00010a05', '\U00010a06'), ('\U00010a0c',
+ '\U00010a13'), ('\U00010a15', '\U00010a17'), ('\U00010a19', '\U00010a33'), ('\U00010a38',
+ '\U00010a3a'), ('\U00010a3f', '\U00010a3f'), ('\U00010a60', '\U00010a7c'), ('\U00010a80',
+ '\U00010a9c'), ('\U00010ac0', '\U00010ac7'), ('\U00010ac9', '\U00010ae6'), ('\U00010b00',
+ '\U00010b35'), ('\U00010b40', '\U00010b55'), ('\U00010b60', '\U00010b72'), ('\U00010b80',
+ '\U00010b91'), ('\U00010c00', '\U00010c48'), ('\U00011000', '\U00011046'), ('\U00011066',
+ '\U0001106f'), ('\U0001107f', '\U000110ba'), ('\U000110d0', '\U000110e8'), ('\U000110f0',
+ '\U000110f9'), ('\U00011100', '\U00011134'), ('\U00011136', '\U0001113f'), ('\U00011150',
+ '\U00011173'), ('\U00011176', '\U00011176'), ('\U00011180', '\U000111c4'), ('\U000111d0',
+ '\U000111da'), ('\U00011200', '\U00011211'), ('\U00011213', '\U00011237'), ('\U000112b0',
+ '\U000112ea'), ('\U000112f0', '\U000112f9'), ('\U00011301', '\U00011303'), ('\U00011305',
+ '\U0001130c'), ('\U0001130f', '\U00011310'), ('\U00011313', '\U00011328'), ('\U0001132a',
+ '\U00011330'), ('\U00011332', '\U00011333'), ('\U00011335', '\U00011339'), ('\U0001133c',
+ '\U00011344'), ('\U00011347', '\U00011348'), ('\U0001134b', '\U0001134d'), ('\U00011357',
+ '\U00011357'), ('\U0001135d', '\U00011363'), ('\U00011366', '\U0001136c'), ('\U00011370',
+ '\U00011374'), ('\U00011480', '\U000114c5'), ('\U000114c7', '\U000114c7'), ('\U000114d0',
+ '\U000114d9'), ('\U00011580', '\U000115b5'), ('\U000115b8', '\U000115c0'), ('\U00011600',
+ '\U00011640'), ('\U00011644', '\U00011644'), ('\U00011650', '\U00011659'), ('\U00011680',
+ '\U000116b7'), ('\U000116c0', '\U000116c9'), ('\U000118a0', '\U000118e9'), ('\U000118ff',
+ '\U000118ff'), ('\U00011ac0', '\U00011af8'), ('\U00012000', '\U00012398'), ('\U00012400',
+ '\U0001246e'), ('\U00013000', '\U0001342e'), ('\U00016800', '\U00016a38'), ('\U00016a40',
+ '\U00016a5e'), ('\U00016a60', '\U00016a69'), ('\U00016ad0', '\U00016aed'), ('\U00016af0',
+ '\U00016af4'), ('\U00016b00', '\U00016b36'), ('\U00016b40', '\U00016b43'), ('\U00016b50',
+ '\U00016b59'), ('\U00016b63', '\U00016b77'), ('\U00016b7d', '\U00016b8f'), ('\U00016f00',
+ '\U00016f44'), ('\U00016f50', '\U00016f7e'), ('\U00016f8f', '\U00016f9f'), ('\U0001b000',
+ '\U0001b001'), ('\U0001bc00', '\U0001bc6a'), ('\U0001bc70', '\U0001bc7c'), ('\U0001bc80',
+ '\U0001bc88'), ('\U0001bc90', '\U0001bc99'), ('\U0001bc9d', '\U0001bc9e'), ('\U0001d165',
+ '\U0001d169'), ('\U0001d16d', '\U0001d172'), ('\U0001d17b', '\U0001d182'), ('\U0001d185',
+ '\U0001d18b'), ('\U0001d1aa', '\U0001d1ad'), ('\U0001d242', '\U0001d244'), ('\U0001d400',
+ '\U0001d454'), ('\U0001d456', '\U0001d49c'), ('\U0001d49e', '\U0001d49f'), ('\U0001d4a2',
+ '\U0001d4a2'), ('\U0001d4a5', '\U0001d4a6'), ('\U0001d4a9', '\U0001d4ac'), ('\U0001d4ae',
+ '\U0001d4b9'), ('\U0001d4bb', '\U0001d4bb'), ('\U0001d4bd', '\U0001d4c3'), ('\U0001d4c5',
+ '\U0001d505'), ('\U0001d507', '\U0001d50a'), ('\U0001d50d', '\U0001d514'), ('\U0001d516',
+ '\U0001d51c'), ('\U0001d51e', '\U0001d539'), ('\U0001d53b', '\U0001d53e'), ('\U0001d540',
+ '\U0001d544'), ('\U0001d546', '\U0001d546'), ('\U0001d54a', '\U0001d550'), ('\U0001d552',
+ '\U0001d6a5'), ('\U0001d6a8', '\U0001d6c0'), ('\U0001d6c2', '\U0001d6da'), ('\U0001d6dc',
+ '\U0001d6fa'), ('\U0001d6fc', '\U0001d714'), ('\U0001d716', '\U0001d734'), ('\U0001d736',
+ '\U0001d74e'), ('\U0001d750', '\U0001d76e'), ('\U0001d770', '\U0001d788'), ('\U0001d78a',
+ '\U0001d7a8'), ('\U0001d7aa', '\U0001d7c2'), ('\U0001d7c4', '\U0001d7cb'), ('\U0001d7ce',
+ '\U0001d7ff'), ('\U0001e800', '\U0001e8c4'), ('\U0001e8d0', '\U0001e8d6'), ('\U0001ee00',
+ '\U0001ee03'), ('\U0001ee05', '\U0001ee1f'), ('\U0001ee21', '\U0001ee22'), ('\U0001ee24',
+ '\U0001ee24'), ('\U0001ee27', '\U0001ee27'), ('\U0001ee29', '\U0001ee32'), ('\U0001ee34',
+ '\U0001ee37'), ('\U0001ee39', '\U0001ee39'), ('\U0001ee3b', '\U0001ee3b'), ('\U0001ee42',
+ '\U0001ee42'), ('\U0001ee47', '\U0001ee47'), ('\U0001ee49', '\U0001ee49'), ('\U0001ee4b',
+ '\U0001ee4b'), ('\U0001ee4d', '\U0001ee4f'), ('\U0001ee51', '\U0001ee52'), ('\U0001ee54',
+ '\U0001ee54'), ('\U0001ee57', '\U0001ee57'), ('\U0001ee59', '\U0001ee59'), ('\U0001ee5b',
+ '\U0001ee5b'), ('\U0001ee5d', '\U0001ee5d'), ('\U0001ee5f', '\U0001ee5f'), ('\U0001ee61',
+ '\U0001ee62'), ('\U0001ee64', '\U0001ee64'), ('\U0001ee67', '\U0001ee6a'), ('\U0001ee6c',
+ '\U0001ee72'), ('\U0001ee74', '\U0001ee77'), ('\U0001ee79', '\U0001ee7c'), ('\U0001ee7e',
+ '\U0001ee7e'), ('\U0001ee80', '\U0001ee89'), ('\U0001ee8b', '\U0001ee9b'), ('\U0001eea1',
+ '\U0001eea3'), ('\U0001eea5', '\U0001eea9'), ('\U0001eeab', '\U0001eebb'), ('\U0001f130',
+ '\U0001f149'), ('\U0001f150', '\U0001f169'), ('\U0001f170', '\U0001f189'), ('\U00020000',
+ '\U0002a6d6'), ('\U0002a700', '\U0002b734'), ('\U0002b740', '\U0002b81d'), ('\U0002f800',
+ '\U0002fa1d'), ('\U000e0100', '\U000e01ef')
+ ];
+
+}
+
+pub mod normalization {
+ // Canonical decompositions
+ pub static canonical_table: &'static [(char, &'static [char])] = &[
+ ('\xc0', &['\x41', '\u0300']), ('\xc1', &['\x41', '\u0301']), ('\xc2', &['\x41', '\u0302']),
+ ('\xc3', &['\x41', '\u0303']), ('\xc4', &['\x41', '\u0308']), ('\xc5', &['\x41', '\u030a']),
+ ('\xc7', &['\x43', '\u0327']), ('\xc8', &['\x45', '\u0300']), ('\xc9', &['\x45', '\u0301']),
+ ('\xca', &['\x45', '\u0302']), ('\xcb', &['\x45', '\u0308']), ('\xcc', &['\x49', '\u0300']),
+ ('\xcd', &['\x49', '\u0301']), ('\xce', &['\x49', '\u0302']), ('\xcf', &['\x49', '\u0308']),
+ ('\xd1', &['\x4e', '\u0303']), ('\xd2', &['\x4f', '\u0300']), ('\xd3', &['\x4f', '\u0301']),
+ ('\xd4', &['\x4f', '\u0302']), ('\xd5', &['\x4f', '\u0303']), ('\xd6', &['\x4f', '\u0308']),
+ ('\xd9', &['\x55', '\u0300']), ('\xda', &['\x55', '\u0301']), ('\xdb', &['\x55', '\u0302']),
+ ('\xdc', &['\x55', '\u0308']), ('\xdd', &['\x59', '\u0301']), ('\xe0', &['\x61', '\u0300']),
+ ('\xe1', &['\x61', '\u0301']), ('\xe2', &['\x61', '\u0302']), ('\xe3', &['\x61', '\u0303']),
+ ('\xe4', &['\x61', '\u0308']), ('\xe5', &['\x61', '\u030a']), ('\xe7', &['\x63', '\u0327']),
+ ('\xe8', &['\x65', '\u0300']), ('\xe9', &['\x65', '\u0301']), ('\xea', &['\x65', '\u0302']),
+ ('\xeb', &['\x65', '\u0308']), ('\xec', &['\x69', '\u0300']), ('\xed', &['\x69', '\u0301']),
+ ('\xee', &['\x69', '\u0302']), ('\xef', &['\x69', '\u0308']), ('\xf1', &['\x6e', '\u0303']),
+ ('\xf2', &['\x6f', '\u0300']), ('\xf3', &['\x6f', '\u0301']), ('\xf4', &['\x6f', '\u0302']),
+ ('\xf5', &['\x6f', '\u0303']), ('\xf6', &['\x6f', '\u0308']), ('\xf9', &['\x75', '\u0300']),
+ ('\xfa', &['\x75', '\u0301']), ('\xfb', &['\x75', '\u0302']), ('\xfc', &['\x75', '\u0308']),
+ ('\xfd', &['\x79', '\u0301']), ('\xff', &['\x79', '\u0308']), ('\u0100', &['\x41',
+ '\u0304']), ('\u0101', &['\x61', '\u0304']), ('\u0102', &['\x41', '\u0306']), ('\u0103',
+ &['\x61', '\u0306']), ('\u0104', &['\x41', '\u0328']), ('\u0105', &['\x61', '\u0328']),
+ ('\u0106', &['\x43', '\u0301']), ('\u0107', &['\x63', '\u0301']), ('\u0108', &['\x43',
+ '\u0302']), ('\u0109', &['\x63', '\u0302']), ('\u010a', &['\x43', '\u0307']), ('\u010b',
+ &['\x63', '\u0307']), ('\u010c', &['\x43', '\u030c']), ('\u010d', &['\x63', '\u030c']),
+ ('\u010e', &['\x44', '\u030c']), ('\u010f', &['\x64', '\u030c']), ('\u0112', &['\x45',
+ '\u0304']), ('\u0113', &['\x65', '\u0304']), ('\u0114', &['\x45', '\u0306']), ('\u0115',
+ &['\x65', '\u0306']), ('\u0116', &['\x45', '\u0307']), ('\u0117', &['\x65', '\u0307']),
+ ('\u0118', &['\x45', '\u0328']), ('\u0119', &['\x65', '\u0328']), ('\u011a', &['\x45',
+ '\u030c']), ('\u011b', &['\x65', '\u030c']), ('\u011c', &['\x47', '\u0302']), ('\u011d',
+ &['\x67', '\u0302']), ('\u011e', &['\x47', '\u0306']), ('\u011f', &['\x67', '\u0306']),
+ ('\u0120', &['\x47', '\u0307']), ('\u0121', &['\x67', '\u0307']), ('\u0122', &['\x47',
+ '\u0327']), ('\u0123', &['\x67', '\u0327']), ('\u0124', &['\x48', '\u0302']), ('\u0125',
+ &['\x68', '\u0302']), ('\u0128', &['\x49', '\u0303']), ('\u0129', &['\x69', '\u0303']),
+ ('\u012a', &['\x49', '\u0304']), ('\u012b', &['\x69', '\u0304']), ('\u012c', &['\x49',
+ '\u0306']), ('\u012d', &['\x69', '\u0306']), ('\u012e', &['\x49', '\u0328']), ('\u012f',
+ &['\x69', '\u0328']), ('\u0130', &['\x49', '\u0307']), ('\u0134', &['\x4a', '\u0302']),
+ ('\u0135', &['\x6a', '\u0302']), ('\u0136', &['\x4b', '\u0327']), ('\u0137', &['\x6b',
+ '\u0327']), ('\u0139', &['\x4c', '\u0301']), ('\u013a', &['\x6c', '\u0301']), ('\u013b',
+ &['\x4c', '\u0327']), ('\u013c', &['\x6c', '\u0327']), ('\u013d', &['\x4c', '\u030c']),
+ ('\u013e', &['\x6c', '\u030c']), ('\u0143', &['\x4e', '\u0301']), ('\u0144', &['\x6e',
+ '\u0301']), ('\u0145', &['\x4e', '\u0327']), ('\u0146', &['\x6e', '\u0327']), ('\u0147',
+ &['\x4e', '\u030c']), ('\u0148', &['\x6e', '\u030c']), ('\u014c', &['\x4f', '\u0304']),
+ ('\u014d', &['\x6f', '\u0304']), ('\u014e', &['\x4f', '\u0306']), ('\u014f', &['\x6f',
+ '\u0306']), ('\u0150', &['\x4f', '\u030b']), ('\u0151', &['\x6f', '\u030b']), ('\u0154',
+ &['\x52', '\u0301']), ('\u0155', &['\x72', '\u0301']), ('\u0156', &['\x52', '\u0327']),
+ ('\u0157', &['\x72', '\u0327']), ('\u0158', &['\x52', '\u030c']), ('\u0159', &['\x72',
+ '\u030c']), ('\u015a', &['\x53', '\u0301']), ('\u015b', &['\x73', '\u0301']), ('\u015c',
+ &['\x53', '\u0302']), ('\u015d', &['\x73', '\u0302']), ('\u015e', &['\x53', '\u0327']),
+ ('\u015f', &['\x73', '\u0327']), ('\u0160', &['\x53', '\u030c']), ('\u0161', &['\x73',
+ '\u030c']), ('\u0162', &['\x54', '\u0327']), ('\u0163', &['\x74', '\u0327']), ('\u0164',
+ &['\x54', '\u030c']), ('\u0165', &['\x74', '\u030c']), ('\u0168', &['\x55', '\u0303']),
+ ('\u0169', &['\x75', '\u0303']), ('\u016a', &['\x55', '\u0304']), ('\u016b', &['\x75',
+ '\u0304']), ('\u016c', &['\x55', '\u0306']), ('\u016d', &['\x75', '\u0306']), ('\u016e',
+ &['\x55', '\u030a']), ('\u016f', &['\x75', '\u030a']), ('\u0170', &['\x55', '\u030b']),
+ ('\u0171', &['\x75', '\u030b']), ('\u0172', &['\x55', '\u0328']), ('\u0173', &['\x75',
+ '\u0328']), ('\u0174', &['\x57', '\u0302']), ('\u0175', &['\x77', '\u0302']), ('\u0176',
+ &['\x59', '\u0302']), ('\u0177', &['\x79', '\u0302']), ('\u0178', &['\x59', '\u0308']),
+ ('\u0179', &['\x5a', '\u0301']), ('\u017a', &['\x7a', '\u0301']), ('\u017b', &['\x5a',
+ '\u0307']), ('\u017c', &['\x7a', '\u0307']), ('\u017d', &['\x5a', '\u030c']), ('\u017e',
+ &['\x7a', '\u030c']), ('\u01a0', &['\x4f', '\u031b']), ('\u01a1', &['\x6f', '\u031b']),
+ ('\u01af', &['\x55', '\u031b']), ('\u01b0', &['\x75', '\u031b']), ('\u01cd', &['\x41',
+ '\u030c']), ('\u01ce', &['\x61', '\u030c']), ('\u01cf', &['\x49', '\u030c']), ('\u01d0',
+ &['\x69', '\u030c']), ('\u01d1', &['\x4f', '\u030c']), ('\u01d2', &['\x6f', '\u030c']),
+ ('\u01d3', &['\x55', '\u030c']), ('\u01d4', &['\x75', '\u030c']), ('\u01d5', &['\xdc',
+ '\u0304']), ('\u01d6', &['\xfc', '\u0304']), ('\u01d7', &['\xdc', '\u0301']), ('\u01d8',
+ &['\xfc', '\u0301']), ('\u01d9', &['\xdc', '\u030c']), ('\u01da', &['\xfc', '\u030c']),
+ ('\u01db', &['\xdc', '\u0300']), ('\u01dc', &['\xfc', '\u0300']), ('\u01de', &['\xc4',
+ '\u0304']), ('\u01df', &['\xe4', '\u0304']), ('\u01e0', &['\u0226', '\u0304']), ('\u01e1',
+ &['\u0227', '\u0304']), ('\u01e2', &['\xc6', '\u0304']), ('\u01e3', &['\xe6', '\u0304']),
+ ('\u01e6', &['\x47', '\u030c']), ('\u01e7', &['\x67', '\u030c']), ('\u01e8', &['\x4b',
+ '\u030c']), ('\u01e9', &['\x6b', '\u030c']), ('\u01ea', &['\x4f', '\u0328']), ('\u01eb',
+ &['\x6f', '\u0328']), ('\u01ec', &['\u01ea', '\u0304']), ('\u01ed', &['\u01eb', '\u0304']),
+ ('\u01ee', &['\u01b7', '\u030c']), ('\u01ef', &['\u0292', '\u030c']), ('\u01f0', &['\x6a',
+ '\u030c']), ('\u01f4', &['\x47', '\u0301']), ('\u01f5', &['\x67', '\u0301']), ('\u01f8',
+ &['\x4e', '\u0300']), ('\u01f9', &['\x6e', '\u0300']), ('\u01fa', &['\xc5', '\u0301']),
+ ('\u01fb', &['\xe5', '\u0301']), ('\u01fc', &['\xc6', '\u0301']), ('\u01fd', &['\xe6',
+ '\u0301']), ('\u01fe', &['\xd8', '\u0301']), ('\u01ff', &['\xf8', '\u0301']), ('\u0200',
+ &['\x41', '\u030f']), ('\u0201', &['\x61', '\u030f']), ('\u0202', &['\x41', '\u0311']),
+ ('\u0203', &['\x61', '\u0311']), ('\u0204', &['\x45', '\u030f']), ('\u0205', &['\x65',
+ '\u030f']), ('\u0206', &['\x45', '\u0311']), ('\u0207', &['\x65', '\u0311']), ('\u0208',
+ &['\x49', '\u030f']), ('\u0209', &['\x69', '\u030f']), ('\u020a', &['\x49', '\u0311']),
+ ('\u020b', &['\x69', '\u0311']), ('\u020c', &['\x4f', '\u030f']), ('\u020d', &['\x6f',
+ '\u030f']), ('\u020e', &['\x4f', '\u0311']), ('\u020f', &['\x6f', '\u0311']), ('\u0210',
+ &['\x52', '\u030f']), ('\u0211', &['\x72', '\u030f']), ('\u0212', &['\x52', '\u0311']),
+ ('\u0213', &['\x72', '\u0311']), ('\u0214', &['\x55', '\u030f']), ('\u0215', &['\x75',
+ '\u030f']), ('\u0216', &['\x55', '\u0311']), ('\u0217', &['\x75', '\u0311']), ('\u0218',
+ &['\x53', '\u0326']), ('\u0219', &['\x73', '\u0326']), ('\u021a', &['\x54', '\u0326']),
+ ('\u021b', &['\x74', '\u0326']), ('\u021e', &['\x48', '\u030c']), ('\u021f', &['\x68',
+ '\u030c']), ('\u0226', &['\x41', '\u0307']), ('\u0227', &['\x61', '\u0307']), ('\u0228',
+ &['\x45', '\u0327']), ('\u0229', &['\x65', '\u0327']), ('\u022a', &['\xd6', '\u0304']),
+ ('\u022b', &['\xf6', '\u0304']), ('\u022c', &['\xd5', '\u0304']), ('\u022d', &['\xf5',
+ '\u0304']), ('\u022e', &['\x4f', '\u0307']), ('\u022f', &['\x6f', '\u0307']), ('\u0230',
+ &['\u022e', '\u0304']), ('\u0231', &['\u022f', '\u0304']), ('\u0232', &['\x59', '\u0304']),
+ ('\u0233', &['\x79', '\u0304']), ('\u0340', &['\u0300']), ('\u0341', &['\u0301']),
+ ('\u0343', &['\u0313']), ('\u0344', &['\u0308', '\u0301']), ('\u0374', &['\u02b9']),
+ ('\u037e', &['\x3b']), ('\u0385', &['\xa8', '\u0301']), ('\u0386', &['\u0391', '\u0301']),
+ ('\u0387', &['\xb7']), ('\u0388', &['\u0395', '\u0301']), ('\u0389', &['\u0397', '\u0301']),
+ ('\u038a', &['\u0399', '\u0301']), ('\u038c', &['\u039f', '\u0301']), ('\u038e', &['\u03a5',
+ '\u0301']), ('\u038f', &['\u03a9', '\u0301']), ('\u0390', &['\u03ca', '\u0301']), ('\u03aa',
+ &['\u0399', '\u0308']), ('\u03ab', &['\u03a5', '\u0308']), ('\u03ac', &['\u03b1',
+ '\u0301']), ('\u03ad', &['\u03b5', '\u0301']), ('\u03ae', &['\u03b7', '\u0301']), ('\u03af',
+ &['\u03b9', '\u0301']), ('\u03b0', &['\u03cb', '\u0301']), ('\u03ca', &['\u03b9',
+ '\u0308']), ('\u03cb', &['\u03c5', '\u0308']), ('\u03cc', &['\u03bf', '\u0301']), ('\u03cd',
+ &['\u03c5', '\u0301']), ('\u03ce', &['\u03c9', '\u0301']), ('\u03d3', &['\u03d2',
+ '\u0301']), ('\u03d4', &['\u03d2', '\u0308']), ('\u0400', &['\u0415', '\u0300']), ('\u0401',
+ &['\u0415', '\u0308']), ('\u0403', &['\u0413', '\u0301']), ('\u0407', &['\u0406',
+ '\u0308']), ('\u040c', &['\u041a', '\u0301']), ('\u040d', &['\u0418', '\u0300']), ('\u040e',
+ &['\u0423', '\u0306']), ('\u0419', &['\u0418', '\u0306']), ('\u0439', &['\u0438',
+ '\u0306']), ('\u0450', &['\u0435', '\u0300']), ('\u0451', &['\u0435', '\u0308']), ('\u0453',
+ &['\u0433', '\u0301']), ('\u0457', &['\u0456', '\u0308']), ('\u045c', &['\u043a',
+ '\u0301']), ('\u045d', &['\u0438', '\u0300']), ('\u045e', &['\u0443', '\u0306']), ('\u0476',
+ &['\u0474', '\u030f']), ('\u0477', &['\u0475', '\u030f']), ('\u04c1', &['\u0416',
+ '\u0306']), ('\u04c2', &['\u0436', '\u0306']), ('\u04d0', &['\u0410', '\u0306']), ('\u04d1',
+ &['\u0430', '\u0306']), ('\u04d2', &['\u0410', '\u0308']), ('\u04d3', &['\u0430',
+ '\u0308']), ('\u04d6', &['\u0415', '\u0306']), ('\u04d7', &['\u0435', '\u0306']), ('\u04da',
+ &['\u04d8', '\u0308']), ('\u04db', &['\u04d9', '\u0308']), ('\u04dc', &['\u0416',
+ '\u0308']), ('\u04dd', &['\u0436', '\u0308']), ('\u04de', &['\u0417', '\u0308']), ('\u04df',
+ &['\u0437', '\u0308']), ('\u04e2', &['\u0418', '\u0304']), ('\u04e3', &['\u0438',
+ '\u0304']), ('\u04e4', &['\u0418', '\u0308']), ('\u04e5', &['\u0438', '\u0308']), ('\u04e6',
+ &['\u041e', '\u0308']), ('\u04e7', &['\u043e', '\u0308']), ('\u04ea', &['\u04e8',
+ '\u0308']), ('\u04eb', &['\u04e9', '\u0308']), ('\u04ec', &['\u042d', '\u0308']), ('\u04ed',
+ &['\u044d', '\u0308']), ('\u04ee', &['\u0423', '\u0304']), ('\u04ef', &['\u0443',
+ '\u0304']), ('\u04f0', &['\u0423', '\u0308']), ('\u04f1', &['\u0443', '\u0308']), ('\u04f2',
+ &['\u0423', '\u030b']), ('\u04f3', &['\u0443', '\u030b']), ('\u04f4', &['\u0427',
+ '\u0308']), ('\u04f5', &['\u0447', '\u0308']), ('\u04f8', &['\u042b', '\u0308']), ('\u04f9',
+ &['\u044b', '\u0308']), ('\u0622', &['\u0627', '\u0653']), ('\u0623', &['\u0627',
+ '\u0654']), ('\u0624', &['\u0648', '\u0654']), ('\u0625', &['\u0627', '\u0655']), ('\u0626',
+ &['\u064a', '\u0654']), ('\u06c0', &['\u06d5', '\u0654']), ('\u06c2', &['\u06c1',
+ '\u0654']), ('\u06d3', &['\u06d2', '\u0654']), ('\u0929', &['\u0928', '\u093c']), ('\u0931',
+ &['\u0930', '\u093c']), ('\u0934', &['\u0933', '\u093c']), ('\u0958', &['\u0915',
+ '\u093c']), ('\u0959', &['\u0916', '\u093c']), ('\u095a', &['\u0917', '\u093c']), ('\u095b',
+ &['\u091c', '\u093c']), ('\u095c', &['\u0921', '\u093c']), ('\u095d', &['\u0922',
+ '\u093c']), ('\u095e', &['\u092b', '\u093c']), ('\u095f', &['\u092f', '\u093c']), ('\u09cb',
+ &['\u09c7', '\u09be']), ('\u09cc', &['\u09c7', '\u09d7']), ('\u09dc', &['\u09a1',
+ '\u09bc']), ('\u09dd', &['\u09a2', '\u09bc']), ('\u09df', &['\u09af', '\u09bc']), ('\u0a33',
+ &['\u0a32', '\u0a3c']), ('\u0a36', &['\u0a38', '\u0a3c']), ('\u0a59', &['\u0a16',
+ '\u0a3c']), ('\u0a5a', &['\u0a17', '\u0a3c']), ('\u0a5b', &['\u0a1c', '\u0a3c']), ('\u0a5e',
+ &['\u0a2b', '\u0a3c']), ('\u0b48', &['\u0b47', '\u0b56']), ('\u0b4b', &['\u0b47',
+ '\u0b3e']), ('\u0b4c', &['\u0b47', '\u0b57']), ('\u0b5c', &['\u0b21', '\u0b3c']), ('\u0b5d',
+ &['\u0b22', '\u0b3c']), ('\u0b94', &['\u0b92', '\u0bd7']), ('\u0bca', &['\u0bc6',
+ '\u0bbe']), ('\u0bcb', &['\u0bc7', '\u0bbe']), ('\u0bcc', &['\u0bc6', '\u0bd7']), ('\u0c48',
+ &['\u0c46', '\u0c56']), ('\u0cc0', &['\u0cbf', '\u0cd5']), ('\u0cc7', &['\u0cc6',
+ '\u0cd5']), ('\u0cc8', &['\u0cc6', '\u0cd6']), ('\u0cca', &['\u0cc6', '\u0cc2']), ('\u0ccb',
+ &['\u0cca', '\u0cd5']), ('\u0d4a', &['\u0d46', '\u0d3e']), ('\u0d4b', &['\u0d47',
+ '\u0d3e']), ('\u0d4c', &['\u0d46', '\u0d57']), ('\u0dda', &['\u0dd9', '\u0dca']), ('\u0ddc',
+ &['\u0dd9', '\u0dcf']), ('\u0ddd', &['\u0ddc', '\u0dca']), ('\u0dde', &['\u0dd9',
+ '\u0ddf']), ('\u0f43', &['\u0f42', '\u0fb7']), ('\u0f4d', &['\u0f4c', '\u0fb7']), ('\u0f52',
+ &['\u0f51', '\u0fb7']), ('\u0f57', &['\u0f56', '\u0fb7']), ('\u0f5c', &['\u0f5b',
+ '\u0fb7']), ('\u0f69', &['\u0f40', '\u0fb5']), ('\u0f73', &['\u0f71', '\u0f72']), ('\u0f75',
+ &['\u0f71', '\u0f74']), ('\u0f76', &['\u0fb2', '\u0f80']), ('\u0f78', &['\u0fb3',
+ '\u0f80']), ('\u0f81', &['\u0f71', '\u0f80']), ('\u0f93', &['\u0f92', '\u0fb7']), ('\u0f9d',
+ &['\u0f9c', '\u0fb7']), ('\u0fa2', &['\u0fa1', '\u0fb7']), ('\u0fa7', &['\u0fa6',
+ '\u0fb7']), ('\u0fac', &['\u0fab', '\u0fb7']), ('\u0fb9', &['\u0f90', '\u0fb5']), ('\u1026',
+ &['\u1025', '\u102e']), ('\u1b06', &['\u1b05', '\u1b35']), ('\u1b08', &['\u1b07',
+ '\u1b35']), ('\u1b0a', &['\u1b09', '\u1b35']), ('\u1b0c', &['\u1b0b', '\u1b35']), ('\u1b0e',
+ &['\u1b0d', '\u1b35']), ('\u1b12', &['\u1b11', '\u1b35']), ('\u1b3b', &['\u1b3a',
+ '\u1b35']), ('\u1b3d', &['\u1b3c', '\u1b35']), ('\u1b40', &['\u1b3e', '\u1b35']), ('\u1b41',
+ &['\u1b3f', '\u1b35']), ('\u1b43', &['\u1b42', '\u1b35']), ('\u1e00', &['\x41', '\u0325']),
+ ('\u1e01', &['\x61', '\u0325']), ('\u1e02', &['\x42', '\u0307']), ('\u1e03', &['\x62',
+ '\u0307']), ('\u1e04', &['\x42', '\u0323']), ('\u1e05', &['\x62', '\u0323']), ('\u1e06',
+ &['\x42', '\u0331']), ('\u1e07', &['\x62', '\u0331']), ('\u1e08', &['\xc7', '\u0301']),
+ ('\u1e09', &['\xe7', '\u0301']), ('\u1e0a', &['\x44', '\u0307']), ('\u1e0b', &['\x64',
+ '\u0307']), ('\u1e0c', &['\x44', '\u0323']), ('\u1e0d', &['\x64', '\u0323']), ('\u1e0e',
+ &['\x44', '\u0331']), ('\u1e0f', &['\x64', '\u0331']), ('\u1e10', &['\x44', '\u0327']),
+ ('\u1e11', &['\x64', '\u0327']), ('\u1e12', &['\x44', '\u032d']), ('\u1e13', &['\x64',
+ '\u032d']), ('\u1e14', &['\u0112', '\u0300']), ('\u1e15', &['\u0113', '\u0300']), ('\u1e16',
+ &['\u0112', '\u0301']), ('\u1e17', &['\u0113', '\u0301']), ('\u1e18', &['\x45', '\u032d']),
+ ('\u1e19', &['\x65', '\u032d']), ('\u1e1a', &['\x45', '\u0330']), ('\u1e1b', &['\x65',
+ '\u0330']), ('\u1e1c', &['\u0228', '\u0306']), ('\u1e1d', &['\u0229', '\u0306']), ('\u1e1e',
+ &['\x46', '\u0307']), ('\u1e1f', &['\x66', '\u0307']), ('\u1e20', &['\x47', '\u0304']),
+ ('\u1e21', &['\x67', '\u0304']), ('\u1e22', &['\x48', '\u0307']), ('\u1e23', &['\x68',
+ '\u0307']), ('\u1e24', &['\x48', '\u0323']), ('\u1e25', &['\x68', '\u0323']), ('\u1e26',
+ &['\x48', '\u0308']), ('\u1e27', &['\x68', '\u0308']), ('\u1e28', &['\x48', '\u0327']),
+ ('\u1e29', &['\x68', '\u0327']), ('\u1e2a', &['\x48', '\u032e']), ('\u1e2b', &['\x68',
+ '\u032e']), ('\u1e2c', &['\x49', '\u0330']), ('\u1e2d', &['\x69', '\u0330']), ('\u1e2e',
+ &['\xcf', '\u0301']), ('\u1e2f', &['\xef', '\u0301']), ('\u1e30', &['\x4b', '\u0301']),
+ ('\u1e31', &['\x6b', '\u0301']), ('\u1e32', &['\x4b', '\u0323']), ('\u1e33', &['\x6b',
+ '\u0323']), ('\u1e34', &['\x4b', '\u0331']), ('\u1e35', &['\x6b', '\u0331']), ('\u1e36',
+ &['\x4c', '\u0323']), ('\u1e37', &['\x6c', '\u0323']), ('\u1e38', &['\u1e36', '\u0304']),
+ ('\u1e39', &['\u1e37', '\u0304']), ('\u1e3a', &['\x4c', '\u0331']), ('\u1e3b', &['\x6c',
+ '\u0331']), ('\u1e3c', &['\x4c', '\u032d']), ('\u1e3d', &['\x6c', '\u032d']), ('\u1e3e',
+ &['\x4d', '\u0301']), ('\u1e3f', &['\x6d', '\u0301']), ('\u1e40', &['\x4d', '\u0307']),
+ ('\u1e41', &['\x6d', '\u0307']), ('\u1e42', &['\x4d', '\u0323']), ('\u1e43', &['\x6d',
+ '\u0323']), ('\u1e44', &['\x4e', '\u0307']), ('\u1e45', &['\x6e', '\u0307']), ('\u1e46',
+ &['\x4e', '\u0323']), ('\u1e47', &['\x6e', '\u0323']), ('\u1e48', &['\x4e', '\u0331']),
+ ('\u1e49', &['\x6e', '\u0331']), ('\u1e4a', &['\x4e', '\u032d']), ('\u1e4b', &['\x6e',
+ '\u032d']), ('\u1e4c', &['\xd5', '\u0301']), ('\u1e4d', &['\xf5', '\u0301']), ('\u1e4e',
+ &['\xd5', '\u0308']), ('\u1e4f', &['\xf5', '\u0308']), ('\u1e50', &['\u014c', '\u0300']),
+ ('\u1e51', &['\u014d', '\u0300']), ('\u1e52', &['\u014c', '\u0301']), ('\u1e53', &['\u014d',
+ '\u0301']), ('\u1e54', &['\x50', '\u0301']), ('\u1e55', &['\x70', '\u0301']), ('\u1e56',
+ &['\x50', '\u0307']), ('\u1e57', &['\x70', '\u0307']), ('\u1e58', &['\x52', '\u0307']),
+ ('\u1e59', &['\x72', '\u0307']), ('\u1e5a', &['\x52', '\u0323']), ('\u1e5b', &['\x72',
+ '\u0323']), ('\u1e5c', &['\u1e5a', '\u0304']), ('\u1e5d', &['\u1e5b', '\u0304']), ('\u1e5e',
+ &['\x52', '\u0331']), ('\u1e5f', &['\x72', '\u0331']), ('\u1e60', &['\x53', '\u0307']),
+ ('\u1e61', &['\x73', '\u0307']), ('\u1e62', &['\x53', '\u0323']), ('\u1e63', &['\x73',
+ '\u0323']), ('\u1e64', &['\u015a', '\u0307']), ('\u1e65', &['\u015b', '\u0307']), ('\u1e66',
+ &['\u0160', '\u0307']), ('\u1e67', &['\u0161', '\u0307']), ('\u1e68', &['\u1e62',
+ '\u0307']), ('\u1e69', &['\u1e63', '\u0307']), ('\u1e6a', &['\x54', '\u0307']), ('\u1e6b',
+ &['\x74', '\u0307']), ('\u1e6c', &['\x54', '\u0323']), ('\u1e6d', &['\x74', '\u0323']),
+ ('\u1e6e', &['\x54', '\u0331']), ('\u1e6f', &['\x74', '\u0331']), ('\u1e70', &['\x54',
+ '\u032d']), ('\u1e71', &['\x74', '\u032d']), ('\u1e72', &['\x55', '\u0324']), ('\u1e73',
+ &['\x75', '\u0324']), ('\u1e74', &['\x55', '\u0330']), ('\u1e75', &['\x75', '\u0330']),
+ ('\u1e76', &['\x55', '\u032d']), ('\u1e77', &['\x75', '\u032d']), ('\u1e78', &['\u0168',
+ '\u0301']), ('\u1e79', &['\u0169', '\u0301']), ('\u1e7a', &['\u016a', '\u0308']), ('\u1e7b',
+ &['\u016b', '\u0308']), ('\u1e7c', &['\x56', '\u0303']), ('\u1e7d', &['\x76', '\u0303']),
+ ('\u1e7e', &['\x56', '\u0323']), ('\u1e7f', &['\x76', '\u0323']), ('\u1e80', &['\x57',
+ '\u0300']), ('\u1e81', &['\x77', '\u0300']), ('\u1e82', &['\x57', '\u0301']), ('\u1e83',
+ &['\x77', '\u0301']), ('\u1e84', &['\x57', '\u0308']), ('\u1e85', &['\x77', '\u0308']),
+ ('\u1e86', &['\x57', '\u0307']), ('\u1e87', &['\x77', '\u0307']), ('\u1e88', &['\x57',
+ '\u0323']), ('\u1e89', &['\x77', '\u0323']), ('\u1e8a', &['\x58', '\u0307']), ('\u1e8b',
+ &['\x78', '\u0307']), ('\u1e8c', &['\x58', '\u0308']), ('\u1e8d', &['\x78', '\u0308']),
+ ('\u1e8e', &['\x59', '\u0307']), ('\u1e8f', &['\x79', '\u0307']), ('\u1e90', &['\x5a',
+ '\u0302']), ('\u1e91', &['\x7a', '\u0302']), ('\u1e92', &['\x5a', '\u0323']), ('\u1e93',
+ &['\x7a', '\u0323']), ('\u1e94', &['\x5a', '\u0331']), ('\u1e95', &['\x7a', '\u0331']),
+ ('\u1e96', &['\x68', '\u0331']), ('\u1e97', &['\x74', '\u0308']), ('\u1e98', &['\x77',
+ '\u030a']), ('\u1e99', &['\x79', '\u030a']), ('\u1e9b', &['\u017f', '\u0307']), ('\u1ea0',
+ &['\x41', '\u0323']), ('\u1ea1', &['\x61', '\u0323']), ('\u1ea2', &['\x41', '\u0309']),
+ ('\u1ea3', &['\x61', '\u0309']), ('\u1ea4', &['\xc2', '\u0301']), ('\u1ea5', &['\xe2',
+ '\u0301']), ('\u1ea6', &['\xc2', '\u0300']), ('\u1ea7', &['\xe2', '\u0300']), ('\u1ea8',
+ &['\xc2', '\u0309']), ('\u1ea9', &['\xe2', '\u0309']), ('\u1eaa', &['\xc2', '\u0303']),
+ ('\u1eab', &['\xe2', '\u0303']), ('\u1eac', &['\u1ea0', '\u0302']), ('\u1ead', &['\u1ea1',
+ '\u0302']), ('\u1eae', &['\u0102', '\u0301']), ('\u1eaf', &['\u0103', '\u0301']), ('\u1eb0',
+ &['\u0102', '\u0300']), ('\u1eb1', &['\u0103', '\u0300']), ('\u1eb2', &['\u0102',
+ '\u0309']), ('\u1eb3', &['\u0103', '\u0309']), ('\u1eb4', &['\u0102', '\u0303']), ('\u1eb5',
+ &['\u0103', '\u0303']), ('\u1eb6', &['\u1ea0', '\u0306']), ('\u1eb7', &['\u1ea1',
+ '\u0306']), ('\u1eb8', &['\x45', '\u0323']), ('\u1eb9', &['\x65', '\u0323']), ('\u1eba',
+ &['\x45', '\u0309']), ('\u1ebb', &['\x65', '\u0309']), ('\u1ebc', &['\x45', '\u0303']),
+ ('\u1ebd', &['\x65', '\u0303']), ('\u1ebe', &['\xca', '\u0301']), ('\u1ebf', &['\xea',
+ '\u0301']), ('\u1ec0', &['\xca', '\u0300']), ('\u1ec1', &['\xea', '\u0300']), ('\u1ec2',
+ &['\xca', '\u0309']), ('\u1ec3', &['\xea', '\u0309']), ('\u1ec4', &['\xca', '\u0303']),
+ ('\u1ec5', &['\xea', '\u0303']), ('\u1ec6', &['\u1eb8', '\u0302']), ('\u1ec7', &['\u1eb9',
+ '\u0302']), ('\u1ec8', &['\x49', '\u0309']), ('\u1ec9', &['\x69', '\u0309']), ('\u1eca',
+ &['\x49', '\u0323']), ('\u1ecb', &['\x69', '\u0323']), ('\u1ecc', &['\x4f', '\u0323']),
+ ('\u1ecd', &['\x6f', '\u0323']), ('\u1ece', &['\x4f', '\u0309']), ('\u1ecf', &['\x6f',
+ '\u0309']), ('\u1ed0', &['\xd4', '\u0301']), ('\u1ed1', &['\xf4', '\u0301']), ('\u1ed2',
+ &['\xd4', '\u0300']), ('\u1ed3', &['\xf4', '\u0300']), ('\u1ed4', &['\xd4', '\u0309']),
+ ('\u1ed5', &['\xf4', '\u0309']), ('\u1ed6', &['\xd4', '\u0303']), ('\u1ed7', &['\xf4',
+ '\u0303']), ('\u1ed8', &['\u1ecc', '\u0302']), ('\u1ed9', &['\u1ecd', '\u0302']), ('\u1eda',
+ &['\u01a0', '\u0301']), ('\u1edb', &['\u01a1', '\u0301']), ('\u1edc', &['\u01a0',
+ '\u0300']), ('\u1edd', &['\u01a1', '\u0300']), ('\u1ede', &['\u01a0', '\u0309']), ('\u1edf',
+ &['\u01a1', '\u0309']), ('\u1ee0', &['\u01a0', '\u0303']), ('\u1ee1', &['\u01a1',
+ '\u0303']), ('\u1ee2', &['\u01a0', '\u0323']), ('\u1ee3', &['\u01a1', '\u0323']), ('\u1ee4',
+ &['\x55', '\u0323']), ('\u1ee5', &['\x75', '\u0323']), ('\u1ee6', &['\x55', '\u0309']),
+ ('\u1ee7', &['\x75', '\u0309']), ('\u1ee8', &['\u01af', '\u0301']), ('\u1ee9', &['\u01b0',
+ '\u0301']), ('\u1eea', &['\u01af', '\u0300']), ('\u1eeb', &['\u01b0', '\u0300']), ('\u1eec',
+ &['\u01af', '\u0309']), ('\u1eed', &['\u01b0', '\u0309']), ('\u1eee', &['\u01af',
+ '\u0303']), ('\u1eef', &['\u01b0', '\u0303']), ('\u1ef0', &['\u01af', '\u0323']), ('\u1ef1',
+ &['\u01b0', '\u0323']), ('\u1ef2', &['\x59', '\u0300']), ('\u1ef3', &['\x79', '\u0300']),
+ ('\u1ef4', &['\x59', '\u0323']), ('\u1ef5', &['\x79', '\u0323']), ('\u1ef6', &['\x59',
+ '\u0309']), ('\u1ef7', &['\x79', '\u0309']), ('\u1ef8', &['\x59', '\u0303']), ('\u1ef9',
+ &['\x79', '\u0303']), ('\u1f00', &['\u03b1', '\u0313']), ('\u1f01', &['\u03b1', '\u0314']),
+ ('\u1f02', &['\u1f00', '\u0300']), ('\u1f03', &['\u1f01', '\u0300']), ('\u1f04', &['\u1f00',
+ '\u0301']), ('\u1f05', &['\u1f01', '\u0301']), ('\u1f06', &['\u1f00', '\u0342']), ('\u1f07',
+ &['\u1f01', '\u0342']), ('\u1f08', &['\u0391', '\u0313']), ('\u1f09', &['\u0391',
+ '\u0314']), ('\u1f0a', &['\u1f08', '\u0300']), ('\u1f0b', &['\u1f09', '\u0300']), ('\u1f0c',
+ &['\u1f08', '\u0301']), ('\u1f0d', &['\u1f09', '\u0301']), ('\u1f0e', &['\u1f08',
+ '\u0342']), ('\u1f0f', &['\u1f09', '\u0342']), ('\u1f10', &['\u03b5', '\u0313']), ('\u1f11',
+ &['\u03b5', '\u0314']), ('\u1f12', &['\u1f10', '\u0300']), ('\u1f13', &['\u1f11',
+ '\u0300']), ('\u1f14', &['\u1f10', '\u0301']), ('\u1f15', &['\u1f11', '\u0301']), ('\u1f18',
+ &['\u0395', '\u0313']), ('\u1f19', &['\u0395', '\u0314']), ('\u1f1a', &['\u1f18',
+ '\u0300']), ('\u1f1b', &['\u1f19', '\u0300']), ('\u1f1c', &['\u1f18', '\u0301']), ('\u1f1d',
+ &['\u1f19', '\u0301']), ('\u1f20', &['\u03b7', '\u0313']), ('\u1f21', &['\u03b7',
+ '\u0314']), ('\u1f22', &['\u1f20', '\u0300']), ('\u1f23', &['\u1f21', '\u0300']), ('\u1f24',
+ &['\u1f20', '\u0301']), ('\u1f25', &['\u1f21', '\u0301']), ('\u1f26', &['\u1f20',
+ '\u0342']), ('\u1f27', &['\u1f21', '\u0342']), ('\u1f28', &['\u0397', '\u0313']), ('\u1f29',
+ &['\u0397', '\u0314']), ('\u1f2a', &['\u1f28', '\u0300']), ('\u1f2b', &['\u1f29',
+ '\u0300']), ('\u1f2c', &['\u1f28', '\u0301']), ('\u1f2d', &['\u1f29', '\u0301']), ('\u1f2e',
+ &['\u1f28', '\u0342']), ('\u1f2f', &['\u1f29', '\u0342']), ('\u1f30', &['\u03b9',
+ '\u0313']), ('\u1f31', &['\u03b9', '\u0314']), ('\u1f32', &['\u1f30', '\u0300']), ('\u1f33',
+ &['\u1f31', '\u0300']), ('\u1f34', &['\u1f30', '\u0301']), ('\u1f35', &['\u1f31',
+ '\u0301']), ('\u1f36', &['\u1f30', '\u0342']), ('\u1f37', &['\u1f31', '\u0342']), ('\u1f38',
+ &['\u0399', '\u0313']), ('\u1f39', &['\u0399', '\u0314']), ('\u1f3a', &['\u1f38',
+ '\u0300']), ('\u1f3b', &['\u1f39', '\u0300']), ('\u1f3c', &['\u1f38', '\u0301']), ('\u1f3d',
+ &['\u1f39', '\u0301']), ('\u1f3e', &['\u1f38', '\u0342']), ('\u1f3f', &['\u1f39',
+ '\u0342']), ('\u1f40', &['\u03bf', '\u0313']), ('\u1f41', &['\u03bf', '\u0314']), ('\u1f42',
+ &['\u1f40', '\u0300']), ('\u1f43', &['\u1f41', '\u0300']), ('\u1f44', &['\u1f40',
+ '\u0301']), ('\u1f45', &['\u1f41', '\u0301']), ('\u1f48', &['\u039f', '\u0313']), ('\u1f49',
+ &['\u039f', '\u0314']), ('\u1f4a', &['\u1f48', '\u0300']), ('\u1f4b', &['\u1f49',
+ '\u0300']), ('\u1f4c', &['\u1f48', '\u0301']), ('\u1f4d', &['\u1f49', '\u0301']), ('\u1f50',
+ &['\u03c5', '\u0313']), ('\u1f51', &['\u03c5', '\u0314']), ('\u1f52', &['\u1f50',
+ '\u0300']), ('\u1f53', &['\u1f51', '\u0300']), ('\u1f54', &['\u1f50', '\u0301']), ('\u1f55',
+ &['\u1f51', '\u0301']), ('\u1f56', &['\u1f50', '\u0342']), ('\u1f57', &['\u1f51',
+ '\u0342']), ('\u1f59', &['\u03a5', '\u0314']), ('\u1f5b', &['\u1f59', '\u0300']), ('\u1f5d',
+ &['\u1f59', '\u0301']), ('\u1f5f', &['\u1f59', '\u0342']), ('\u1f60', &['\u03c9',
+ '\u0313']), ('\u1f61', &['\u03c9', '\u0314']), ('\u1f62', &['\u1f60', '\u0300']), ('\u1f63',
+ &['\u1f61', '\u0300']), ('\u1f64', &['\u1f60', '\u0301']), ('\u1f65', &['\u1f61',
+ '\u0301']), ('\u1f66', &['\u1f60', '\u0342']), ('\u1f67', &['\u1f61', '\u0342']), ('\u1f68',
+ &['\u03a9', '\u0313']), ('\u1f69', &['\u03a9', '\u0314']), ('\u1f6a', &['\u1f68',
+ '\u0300']), ('\u1f6b', &['\u1f69', '\u0300']), ('\u1f6c', &['\u1f68', '\u0301']), ('\u1f6d',
+ &['\u1f69', '\u0301']), ('\u1f6e', &['\u1f68', '\u0342']), ('\u1f6f', &['\u1f69',
+ '\u0342']), ('\u1f70', &['\u03b1', '\u0300']), ('\u1f71', &['\u03ac']), ('\u1f72',
+ &['\u03b5', '\u0300']), ('\u1f73', &['\u03ad']), ('\u1f74', &['\u03b7', '\u0300']),
+ ('\u1f75', &['\u03ae']), ('\u1f76', &['\u03b9', '\u0300']), ('\u1f77', &['\u03af']),
+ ('\u1f78', &['\u03bf', '\u0300']), ('\u1f79', &['\u03cc']), ('\u1f7a', &['\u03c5',
+ '\u0300']), ('\u1f7b', &['\u03cd']), ('\u1f7c', &['\u03c9', '\u0300']), ('\u1f7d',
+ &['\u03ce']), ('\u1f80', &['\u1f00', '\u0345']), ('\u1f81', &['\u1f01', '\u0345']),
+ ('\u1f82', &['\u1f02', '\u0345']), ('\u1f83', &['\u1f03', '\u0345']), ('\u1f84', &['\u1f04',
+ '\u0345']), ('\u1f85', &['\u1f05', '\u0345']), ('\u1f86', &['\u1f06', '\u0345']), ('\u1f87',
+ &['\u1f07', '\u0345']), ('\u1f88', &['\u1f08', '\u0345']), ('\u1f89', &['\u1f09',
+ '\u0345']), ('\u1f8a', &['\u1f0a', '\u0345']), ('\u1f8b', &['\u1f0b', '\u0345']), ('\u1f8c',
+ &['\u1f0c', '\u0345']), ('\u1f8d', &['\u1f0d', '\u0345']), ('\u1f8e', &['\u1f0e',
+ '\u0345']), ('\u1f8f', &['\u1f0f', '\u0345']), ('\u1f90', &['\u1f20', '\u0345']), ('\u1f91',
+ &['\u1f21', '\u0345']), ('\u1f92', &['\u1f22', '\u0345']), ('\u1f93', &['\u1f23',
+ '\u0345']), ('\u1f94', &['\u1f24', '\u0345']), ('\u1f95', &['\u1f25', '\u0345']), ('\u1f96',
+ &['\u1f26', '\u0345']), ('\u1f97', &['\u1f27', '\u0345']), ('\u1f98', &['\u1f28',
+ '\u0345']), ('\u1f99', &['\u1f29', '\u0345']), ('\u1f9a', &['\u1f2a', '\u0345']), ('\u1f9b',
+ &['\u1f2b', '\u0345']), ('\u1f9c', &['\u1f2c', '\u0345']), ('\u1f9d', &['\u1f2d',
+ '\u0345']), ('\u1f9e', &['\u1f2e', '\u0345']), ('\u1f9f', &['\u1f2f', '\u0345']), ('\u1fa0',
+ &['\u1f60', '\u0345']), ('\u1fa1', &['\u1f61', '\u0345']), ('\u1fa2', &['\u1f62',
+ '\u0345']), ('\u1fa3', &['\u1f63', '\u0345']), ('\u1fa4', &['\u1f64', '\u0345']), ('\u1fa5',
+ &['\u1f65', '\u0345']), ('\u1fa6', &['\u1f66', '\u0345']), ('\u1fa7', &['\u1f67',
+ '\u0345']), ('\u1fa8', &['\u1f68', '\u0345']), ('\u1fa9', &['\u1f69', '\u0345']), ('\u1faa',
+ &['\u1f6a', '\u0345']), ('\u1fab', &['\u1f6b', '\u0345']), ('\u1fac', &['\u1f6c',
+ '\u0345']), ('\u1fad', &['\u1f6d', '\u0345']), ('\u1fae', &['\u1f6e', '\u0345']), ('\u1faf',
+ &['\u1f6f', '\u0345']), ('\u1fb0', &['\u03b1', '\u0306']), ('\u1fb1', &['\u03b1',
+ '\u0304']), ('\u1fb2', &['\u1f70', '\u0345']), ('\u1fb3', &['\u03b1', '\u0345']), ('\u1fb4',
+ &['\u03ac', '\u0345']), ('\u1fb6', &['\u03b1', '\u0342']), ('\u1fb7', &['\u1fb6',
+ '\u0345']), ('\u1fb8', &['\u0391', '\u0306']), ('\u1fb9', &['\u0391', '\u0304']), ('\u1fba',
+ &['\u0391', '\u0300']), ('\u1fbb', &['\u0386']), ('\u1fbc', &['\u0391', '\u0345']),
+ ('\u1fbe', &['\u03b9']), ('\u1fc1', &['\xa8', '\u0342']), ('\u1fc2', &['\u1f74', '\u0345']),
+ ('\u1fc3', &['\u03b7', '\u0345']), ('\u1fc4', &['\u03ae', '\u0345']), ('\u1fc6', &['\u03b7',
+ '\u0342']), ('\u1fc7', &['\u1fc6', '\u0345']), ('\u1fc8', &['\u0395', '\u0300']), ('\u1fc9',
+ &['\u0388']), ('\u1fca', &['\u0397', '\u0300']), ('\u1fcb', &['\u0389']), ('\u1fcc',
+ &['\u0397', '\u0345']), ('\u1fcd', &['\u1fbf', '\u0300']), ('\u1fce', &['\u1fbf',
+ '\u0301']), ('\u1fcf', &['\u1fbf', '\u0342']), ('\u1fd0', &['\u03b9', '\u0306']), ('\u1fd1',
+ &['\u03b9', '\u0304']), ('\u1fd2', &['\u03ca', '\u0300']), ('\u1fd3', &['\u0390']),
+ ('\u1fd6', &['\u03b9', '\u0342']), ('\u1fd7', &['\u03ca', '\u0342']), ('\u1fd8', &['\u0399',
+ '\u0306']), ('\u1fd9', &['\u0399', '\u0304']), ('\u1fda', &['\u0399', '\u0300']), ('\u1fdb',
+ &['\u038a']), ('\u1fdd', &['\u1ffe', '\u0300']), ('\u1fde', &['\u1ffe', '\u0301']),
+ ('\u1fdf', &['\u1ffe', '\u0342']), ('\u1fe0', &['\u03c5', '\u0306']), ('\u1fe1', &['\u03c5',
+ '\u0304']), ('\u1fe2', &['\u03cb', '\u0300']), ('\u1fe3', &['\u03b0']), ('\u1fe4',
+ &['\u03c1', '\u0313']), ('\u1fe5', &['\u03c1', '\u0314']), ('\u1fe6', &['\u03c5',
+ '\u0342']), ('\u1fe7', &['\u03cb', '\u0342']), ('\u1fe8', &['\u03a5', '\u0306']), ('\u1fe9',
+ &['\u03a5', '\u0304']), ('\u1fea', &['\u03a5', '\u0300']), ('\u1feb', &['\u038e']),
+ ('\u1fec', &['\u03a1', '\u0314']), ('\u1fed', &['\xa8', '\u0300']), ('\u1fee', &['\u0385']),
+ ('\u1fef', &['\x60']), ('\u1ff2', &['\u1f7c', '\u0345']), ('\u1ff3', &['\u03c9', '\u0345']),
+ ('\u1ff4', &['\u03ce', '\u0345']), ('\u1ff6', &['\u03c9', '\u0342']), ('\u1ff7', &['\u1ff6',
+ '\u0345']), ('\u1ff8', &['\u039f', '\u0300']), ('\u1ff9', &['\u038c']), ('\u1ffa',
+ &['\u03a9', '\u0300']), ('\u1ffb', &['\u038f']), ('\u1ffc', &['\u03a9', '\u0345']),
+ ('\u1ffd', &['\xb4']), ('\u2000', &['\u2002']), ('\u2001', &['\u2003']), ('\u2126',
+ &['\u03a9']), ('\u212a', &['\x4b']), ('\u212b', &['\xc5']), ('\u219a', &['\u2190',
+ '\u0338']), ('\u219b', &['\u2192', '\u0338']), ('\u21ae', &['\u2194', '\u0338']), ('\u21cd',
+ &['\u21d0', '\u0338']), ('\u21ce', &['\u21d4', '\u0338']), ('\u21cf', &['\u21d2',
+ '\u0338']), ('\u2204', &['\u2203', '\u0338']), ('\u2209', &['\u2208', '\u0338']), ('\u220c',
+ &['\u220b', '\u0338']), ('\u2224', &['\u2223', '\u0338']), ('\u2226', &['\u2225',
+ '\u0338']), ('\u2241', &['\u223c', '\u0338']), ('\u2244', &['\u2243', '\u0338']), ('\u2247',
+ &['\u2245', '\u0338']), ('\u2249', &['\u2248', '\u0338']), ('\u2260', &['\x3d', '\u0338']),
+ ('\u2262', &['\u2261', '\u0338']), ('\u226d', &['\u224d', '\u0338']), ('\u226e', &['\x3c',
+ '\u0338']), ('\u226f', &['\x3e', '\u0338']), ('\u2270', &['\u2264', '\u0338']), ('\u2271',
+ &['\u2265', '\u0338']), ('\u2274', &['\u2272', '\u0338']), ('\u2275', &['\u2273',
+ '\u0338']), ('\u2278', &['\u2276', '\u0338']), ('\u2279', &['\u2277', '\u0338']), ('\u2280',
+ &['\u227a', '\u0338']), ('\u2281', &['\u227b', '\u0338']), ('\u2284', &['\u2282',
+ '\u0338']), ('\u2285', &['\u2283', '\u0338']), ('\u2288', &['\u2286', '\u0338']), ('\u2289',
+ &['\u2287', '\u0338']), ('\u22ac', &['\u22a2', '\u0338']), ('\u22ad', &['\u22a8',
+ '\u0338']), ('\u22ae', &['\u22a9', '\u0338']), ('\u22af', &['\u22ab', '\u0338']), ('\u22e0',
+ &['\u227c', '\u0338']), ('\u22e1', &['\u227d', '\u0338']), ('\u22e2', &['\u2291',
+ '\u0338']), ('\u22e3', &['\u2292', '\u0338']), ('\u22ea', &['\u22b2', '\u0338']), ('\u22eb',
+ &['\u22b3', '\u0338']), ('\u22ec', &['\u22b4', '\u0338']), ('\u22ed', &['\u22b5',
+ '\u0338']), ('\u2329', &['\u3008']), ('\u232a', &['\u3009']), ('\u2adc', &['\u2add',
+ '\u0338']), ('\u304c', &['\u304b', '\u3099']), ('\u304e', &['\u304d', '\u3099']), ('\u3050',
+ &['\u304f', '\u3099']), ('\u3052', &['\u3051', '\u3099']), ('\u3054', &['\u3053',
+ '\u3099']), ('\u3056', &['\u3055', '\u3099']), ('\u3058', &['\u3057', '\u3099']), ('\u305a',
+ &['\u3059', '\u3099']), ('\u305c', &['\u305b', '\u3099']), ('\u305e', &['\u305d',
+ '\u3099']), ('\u3060', &['\u305f', '\u3099']), ('\u3062', &['\u3061', '\u3099']), ('\u3065',
+ &['\u3064', '\u3099']), ('\u3067', &['\u3066', '\u3099']), ('\u3069', &['\u3068',
+ '\u3099']), ('\u3070', &['\u306f', '\u3099']), ('\u3071', &['\u306f', '\u309a']), ('\u3073',
+ &['\u3072', '\u3099']), ('\u3074', &['\u3072', '\u309a']), ('\u3076', &['\u3075',
+ '\u3099']), ('\u3077', &['\u3075', '\u309a']), ('\u3079', &['\u3078', '\u3099']), ('\u307a',
+ &['\u3078', '\u309a']), ('\u307c', &['\u307b', '\u3099']), ('\u307d', &['\u307b',
+ '\u309a']), ('\u3094', &['\u3046', '\u3099']), ('\u309e', &['\u309d', '\u3099']), ('\u30ac',
+ &['\u30ab', '\u3099']), ('\u30ae', &['\u30ad', '\u3099']), ('\u30b0', &['\u30af',
+ '\u3099']), ('\u30b2', &['\u30b1', '\u3099']), ('\u30b4', &['\u30b3', '\u3099']), ('\u30b6',
+ &['\u30b5', '\u3099']), ('\u30b8', &['\u30b7', '\u3099']), ('\u30ba', &['\u30b9',
+ '\u3099']), ('\u30bc', &['\u30bb', '\u3099']), ('\u30be', &['\u30bd', '\u3099']), ('\u30c0',
+ &['\u30bf', '\u3099']), ('\u30c2', &['\u30c1', '\u3099']), ('\u30c5', &['\u30c4',
+ '\u3099']), ('\u30c7', &['\u30c6', '\u3099']), ('\u30c9', &['\u30c8', '\u3099']), ('\u30d0',
+ &['\u30cf', '\u3099']), ('\u30d1', &['\u30cf', '\u309a']), ('\u30d3', &['\u30d2',
+ '\u3099']), ('\u30d4', &['\u30d2', '\u309a']), ('\u30d6', &['\u30d5', '\u3099']), ('\u30d7',
+ &['\u30d5', '\u309a']), ('\u30d9', &['\u30d8', '\u3099']), ('\u30da', &['\u30d8',
+ '\u309a']), ('\u30dc', &['\u30db', '\u3099']), ('\u30dd', &['\u30db', '\u309a']), ('\u30f4',
+ &['\u30a6', '\u3099']), ('\u30f7', &['\u30ef', '\u3099']), ('\u30f8', &['\u30f0',
+ '\u3099']), ('\u30f9', &['\u30f1', '\u3099']), ('\u30fa', &['\u30f2', '\u3099']), ('\u30fe',
+ &['\u30fd', '\u3099']), ('\uf900', &['\u8c48']), ('\uf901', &['\u66f4']), ('\uf902',
+ &['\u8eca']), ('\uf903', &['\u8cc8']), ('\uf904', &['\u6ed1']), ('\uf905', &['\u4e32']),
+ ('\uf906', &['\u53e5']), ('\uf907', &['\u9f9c']), ('\uf908', &['\u9f9c']), ('\uf909',
+ &['\u5951']), ('\uf90a', &['\u91d1']), ('\uf90b', &['\u5587']), ('\uf90c', &['\u5948']),
+ ('\uf90d', &['\u61f6']), ('\uf90e', &['\u7669']), ('\uf90f', &['\u7f85']), ('\uf910',
+ &['\u863f']), ('\uf911', &['\u87ba']), ('\uf912', &['\u88f8']), ('\uf913', &['\u908f']),
+ ('\uf914', &['\u6a02']), ('\uf915', &['\u6d1b']), ('\uf916', &['\u70d9']), ('\uf917',
+ &['\u73de']), ('\uf918', &['\u843d']), ('\uf919', &['\u916a']), ('\uf91a', &['\u99f1']),
+ ('\uf91b', &['\u4e82']), ('\uf91c', &['\u5375']), ('\uf91d', &['\u6b04']), ('\uf91e',
+ &['\u721b']), ('\uf91f', &['\u862d']), ('\uf920', &['\u9e1e']), ('\uf921', &['\u5d50']),
+ ('\uf922', &['\u6feb']), ('\uf923', &['\u85cd']), ('\uf924', &['\u8964']), ('\uf925',
+ &['\u62c9']), ('\uf926', &['\u81d8']), ('\uf927', &['\u881f']), ('\uf928', &['\u5eca']),
+ ('\uf929', &['\u6717']), ('\uf92a', &['\u6d6a']), ('\uf92b', &['\u72fc']), ('\uf92c',
+ &['\u90ce']), ('\uf92d', &['\u4f86']), ('\uf92e', &['\u51b7']), ('\uf92f', &['\u52de']),
+ ('\uf930', &['\u64c4']), ('\uf931', &['\u6ad3']), ('\uf932', &['\u7210']), ('\uf933',
+ &['\u76e7']), ('\uf934', &['\u8001']), ('\uf935', &['\u8606']), ('\uf936', &['\u865c']),
+ ('\uf937', &['\u8def']), ('\uf938', &['\u9732']), ('\uf939', &['\u9b6f']), ('\uf93a',
+ &['\u9dfa']), ('\uf93b', &['\u788c']), ('\uf93c', &['\u797f']), ('\uf93d', &['\u7da0']),
+ ('\uf93e', &['\u83c9']), ('\uf93f', &['\u9304']), ('\uf940', &['\u9e7f']), ('\uf941',
+ &['\u8ad6']), ('\uf942', &['\u58df']), ('\uf943', &['\u5f04']), ('\uf944', &['\u7c60']),
+ ('\uf945', &['\u807e']), ('\uf946', &['\u7262']), ('\uf947', &['\u78ca']), ('\uf948',
+ &['\u8cc2']), ('\uf949', &['\u96f7']), ('\uf94a', &['\u58d8']), ('\uf94b', &['\u5c62']),
+ ('\uf94c', &['\u6a13']), ('\uf94d', &['\u6dda']), ('\uf94e', &['\u6f0f']), ('\uf94f',
+ &['\u7d2f']), ('\uf950', &['\u7e37']), ('\uf951', &['\u964b']), ('\uf952', &['\u52d2']),
+ ('\uf953', &['\u808b']), ('\uf954', &['\u51dc']), ('\uf955', &['\u51cc']), ('\uf956',
+ &['\u7a1c']), ('\uf957', &['\u7dbe']), ('\uf958', &['\u83f1']), ('\uf959', &['\u9675']),
+ ('\uf95a', &['\u8b80']), ('\uf95b', &['\u62cf']), ('\uf95c', &['\u6a02']), ('\uf95d',
+ &['\u8afe']), ('\uf95e', &['\u4e39']), ('\uf95f', &['\u5be7']), ('\uf960', &['\u6012']),
+ ('\uf961', &['\u7387']), ('\uf962', &['\u7570']), ('\uf963', &['\u5317']), ('\uf964',
+ &['\u78fb']), ('\uf965', &['\u4fbf']), ('\uf966', &['\u5fa9']), ('\uf967', &['\u4e0d']),
+ ('\uf968', &['\u6ccc']), ('\uf969', &['\u6578']), ('\uf96a', &['\u7d22']), ('\uf96b',
+ &['\u53c3']), ('\uf96c', &['\u585e']), ('\uf96d', &['\u7701']), ('\uf96e', &['\u8449']),
+ ('\uf96f', &['\u8aaa']), ('\uf970', &['\u6bba']), ('\uf971', &['\u8fb0']), ('\uf972',
+ &['\u6c88']), ('\uf973', &['\u62fe']), ('\uf974', &['\u82e5']), ('\uf975', &['\u63a0']),
+ ('\uf976', &['\u7565']), ('\uf977', &['\u4eae']), ('\uf978', &['\u5169']), ('\uf979',
+ &['\u51c9']), ('\uf97a', &['\u6881']), ('\uf97b', &['\u7ce7']), ('\uf97c', &['\u826f']),
+ ('\uf97d', &['\u8ad2']), ('\uf97e', &['\u91cf']), ('\uf97f', &['\u52f5']), ('\uf980',
+ &['\u5442']), ('\uf981', &['\u5973']), ('\uf982', &['\u5eec']), ('\uf983', &['\u65c5']),
+ ('\uf984', &['\u6ffe']), ('\uf985', &['\u792a']), ('\uf986', &['\u95ad']), ('\uf987',
+ &['\u9a6a']), ('\uf988', &['\u9e97']), ('\uf989', &['\u9ece']), ('\uf98a', &['\u529b']),
+ ('\uf98b', &['\u66c6']), ('\uf98c', &['\u6b77']), ('\uf98d', &['\u8f62']), ('\uf98e',
+ &['\u5e74']), ('\uf98f', &['\u6190']), ('\uf990', &['\u6200']), ('\uf991', &['\u649a']),
+ ('\uf992', &['\u6f23']), ('\uf993', &['\u7149']), ('\uf994', &['\u7489']), ('\uf995',
+ &['\u79ca']), ('\uf996', &['\u7df4']), ('\uf997', &['\u806f']), ('\uf998', &['\u8f26']),
+ ('\uf999', &['\u84ee']), ('\uf99a', &['\u9023']), ('\uf99b', &['\u934a']), ('\uf99c',
+ &['\u5217']), ('\uf99d', &['\u52a3']), ('\uf99e', &['\u54bd']), ('\uf99f', &['\u70c8']),
+ ('\uf9a0', &['\u88c2']), ('\uf9a1', &['\u8aaa']), ('\uf9a2', &['\u5ec9']), ('\uf9a3',
+ &['\u5ff5']), ('\uf9a4', &['\u637b']), ('\uf9a5', &['\u6bae']), ('\uf9a6', &['\u7c3e']),
+ ('\uf9a7', &['\u7375']), ('\uf9a8', &['\u4ee4']), ('\uf9a9', &['\u56f9']), ('\uf9aa',
+ &['\u5be7']), ('\uf9ab', &['\u5dba']), ('\uf9ac', &['\u601c']), ('\uf9ad', &['\u73b2']),
+ ('\uf9ae', &['\u7469']), ('\uf9af', &['\u7f9a']), ('\uf9b0', &['\u8046']), ('\uf9b1',
+ &['\u9234']), ('\uf9b2', &['\u96f6']), ('\uf9b3', &['\u9748']), ('\uf9b4', &['\u9818']),
+ ('\uf9b5', &['\u4f8b']), ('\uf9b6', &['\u79ae']), ('\uf9b7', &['\u91b4']), ('\uf9b8',
+ &['\u96b8']), ('\uf9b9', &['\u60e1']), ('\uf9ba', &['\u4e86']), ('\uf9bb', &['\u50da']),
+ ('\uf9bc', &['\u5bee']), ('\uf9bd', &['\u5c3f']), ('\uf9be', &['\u6599']), ('\uf9bf',
+ &['\u6a02']), ('\uf9c0', &['\u71ce']), ('\uf9c1', &['\u7642']), ('\uf9c2', &['\u84fc']),
+ ('\uf9c3', &['\u907c']), ('\uf9c4', &['\u9f8d']), ('\uf9c5', &['\u6688']), ('\uf9c6',
+ &['\u962e']), ('\uf9c7', &['\u5289']), ('\uf9c8', &['\u677b']), ('\uf9c9', &['\u67f3']),
+ ('\uf9ca', &['\u6d41']), ('\uf9cb', &['\u6e9c']), ('\uf9cc', &['\u7409']), ('\uf9cd',
+ &['\u7559']), ('\uf9ce', &['\u786b']), ('\uf9cf', &['\u7d10']), ('\uf9d0', &['\u985e']),
+ ('\uf9d1', &['\u516d']), ('\uf9d2', &['\u622e']), ('\uf9d3', &['\u9678']), ('\uf9d4',
+ &['\u502b']), ('\uf9d5', &['\u5d19']), ('\uf9d6', &['\u6dea']), ('\uf9d7', &['\u8f2a']),
+ ('\uf9d8', &['\u5f8b']), ('\uf9d9', &['\u6144']), ('\uf9da', &['\u6817']), ('\uf9db',
+ &['\u7387']), ('\uf9dc', &['\u9686']), ('\uf9dd', &['\u5229']), ('\uf9de', &['\u540f']),
+ ('\uf9df', &['\u5c65']), ('\uf9e0', &['\u6613']), ('\uf9e1', &['\u674e']), ('\uf9e2',
+ &['\u68a8']), ('\uf9e3', &['\u6ce5']), ('\uf9e4', &['\u7406']), ('\uf9e5', &['\u75e2']),
+ ('\uf9e6', &['\u7f79']), ('\uf9e7', &['\u88cf']), ('\uf9e8', &['\u88e1']), ('\uf9e9',
+ &['\u91cc']), ('\uf9ea', &['\u96e2']), ('\uf9eb', &['\u533f']), ('\uf9ec', &['\u6eba']),
+ ('\uf9ed', &['\u541d']), ('\uf9ee', &['\u71d0']), ('\uf9ef', &['\u7498']), ('\uf9f0',
+ &['\u85fa']), ('\uf9f1', &['\u96a3']), ('\uf9f2', &['\u9c57']), ('\uf9f3', &['\u9e9f']),
+ ('\uf9f4', &['\u6797']), ('\uf9f5', &['\u6dcb']), ('\uf9f6', &['\u81e8']), ('\uf9f7',
+ &['\u7acb']), ('\uf9f8', &['\u7b20']), ('\uf9f9', &['\u7c92']), ('\uf9fa', &['\u72c0']),
+ ('\uf9fb', &['\u7099']), ('\uf9fc', &['\u8b58']), ('\uf9fd', &['\u4ec0']), ('\uf9fe',
+ &['\u8336']), ('\uf9ff', &['\u523a']), ('\ufa00', &['\u5207']), ('\ufa01', &['\u5ea6']),
+ ('\ufa02', &['\u62d3']), ('\ufa03', &['\u7cd6']), ('\ufa04', &['\u5b85']), ('\ufa05',
+ &['\u6d1e']), ('\ufa06', &['\u66b4']), ('\ufa07', &['\u8f3b']), ('\ufa08', &['\u884c']),
+ ('\ufa09', &['\u964d']), ('\ufa0a', &['\u898b']), ('\ufa0b', &['\u5ed3']), ('\ufa0c',
+ &['\u5140']), ('\ufa0d', &['\u55c0']), ('\ufa10', &['\u585a']), ('\ufa12', &['\u6674']),
+ ('\ufa15', &['\u51de']), ('\ufa16', &['\u732a']), ('\ufa17', &['\u76ca']), ('\ufa18',
+ &['\u793c']), ('\ufa19', &['\u795e']), ('\ufa1a', &['\u7965']), ('\ufa1b', &['\u798f']),
+ ('\ufa1c', &['\u9756']), ('\ufa1d', &['\u7cbe']), ('\ufa1e', &['\u7fbd']), ('\ufa20',
+ &['\u8612']), ('\ufa22', &['\u8af8']), ('\ufa25', &['\u9038']), ('\ufa26', &['\u90fd']),
+ ('\ufa2a', &['\u98ef']), ('\ufa2b', &['\u98fc']), ('\ufa2c', &['\u9928']), ('\ufa2d',
+ &['\u9db4']), ('\ufa2e', &['\u90de']), ('\ufa2f', &['\u96b7']), ('\ufa30', &['\u4fae']),
+ ('\ufa31', &['\u50e7']), ('\ufa32', &['\u514d']), ('\ufa33', &['\u52c9']), ('\ufa34',
+ &['\u52e4']), ('\ufa35', &['\u5351']), ('\ufa36', &['\u559d']), ('\ufa37', &['\u5606']),
+ ('\ufa38', &['\u5668']), ('\ufa39', &['\u5840']), ('\ufa3a', &['\u58a8']), ('\ufa3b',
+ &['\u5c64']), ('\ufa3c', &['\u5c6e']), ('\ufa3d', &['\u6094']), ('\ufa3e', &['\u6168']),
+ ('\ufa3f', &['\u618e']), ('\ufa40', &['\u61f2']), ('\ufa41', &['\u654f']), ('\ufa42',
+ &['\u65e2']), ('\ufa43', &['\u6691']), ('\ufa44', &['\u6885']), ('\ufa45', &['\u6d77']),
+ ('\ufa46', &['\u6e1a']), ('\ufa47', &['\u6f22']), ('\ufa48', &['\u716e']), ('\ufa49',
+ &['\u722b']), ('\ufa4a', &['\u7422']), ('\ufa4b', &['\u7891']), ('\ufa4c', &['\u793e']),
+ ('\ufa4d', &['\u7949']), ('\ufa4e', &['\u7948']), ('\ufa4f', &['\u7950']), ('\ufa50',
+ &['\u7956']), ('\ufa51', &['\u795d']), ('\ufa52', &['\u798d']), ('\ufa53', &['\u798e']),
+ ('\ufa54', &['\u7a40']), ('\ufa55', &['\u7a81']), ('\ufa56', &['\u7bc0']), ('\ufa57',
+ &['\u7df4']), ('\ufa58', &['\u7e09']), ('\ufa59', &['\u7e41']), ('\ufa5a', &['\u7f72']),
+ ('\ufa5b', &['\u8005']), ('\ufa5c', &['\u81ed']), ('\ufa5d', &['\u8279']), ('\ufa5e',
+ &['\u8279']), ('\ufa5f', &['\u8457']), ('\ufa60', &['\u8910']), ('\ufa61', &['\u8996']),
+ ('\ufa62', &['\u8b01']), ('\ufa63', &['\u8b39']), ('\ufa64', &['\u8cd3']), ('\ufa65',
+ &['\u8d08']), ('\ufa66', &['\u8fb6']), ('\ufa67', &['\u9038']), ('\ufa68', &['\u96e3']),
+ ('\ufa69', &['\u97ff']), ('\ufa6a', &['\u983b']), ('\ufa6b', &['\u6075']), ('\ufa6c',
+ &['\U000242ee']), ('\ufa6d', &['\u8218']), ('\ufa70', &['\u4e26']), ('\ufa71', &['\u51b5']),
+ ('\ufa72', &['\u5168']), ('\ufa73', &['\u4f80']), ('\ufa74', &['\u5145']), ('\ufa75',
+ &['\u5180']), ('\ufa76', &['\u52c7']), ('\ufa77', &['\u52fa']), ('\ufa78', &['\u559d']),
+ ('\ufa79', &['\u5555']), ('\ufa7a', &['\u5599']), ('\ufa7b', &['\u55e2']), ('\ufa7c',
+ &['\u585a']), ('\ufa7d', &['\u58b3']), ('\ufa7e', &['\u5944']), ('\ufa7f', &['\u5954']),
+ ('\ufa80', &['\u5a62']), ('\ufa81', &['\u5b28']), ('\ufa82', &['\u5ed2']), ('\ufa83',
+ &['\u5ed9']), ('\ufa84', &['\u5f69']), ('\ufa85', &['\u5fad']), ('\ufa86', &['\u60d8']),
+ ('\ufa87', &['\u614e']), ('\ufa88', &['\u6108']), ('\ufa89', &['\u618e']), ('\ufa8a',
+ &['\u6160']), ('\ufa8b', &['\u61f2']), ('\ufa8c', &['\u6234']), ('\ufa8d', &['\u63c4']),
+ ('\ufa8e', &['\u641c']), ('\ufa8f', &['\u6452']), ('\ufa90', &['\u6556']), ('\ufa91',
+ &['\u6674']), ('\ufa92', &['\u6717']), ('\ufa93', &['\u671b']), ('\ufa94', &['\u6756']),
+ ('\ufa95', &['\u6b79']), ('\ufa96', &['\u6bba']), ('\ufa97', &['\u6d41']), ('\ufa98',
+ &['\u6edb']), ('\ufa99', &['\u6ecb']), ('\ufa9a', &['\u6f22']), ('\ufa9b', &['\u701e']),
+ ('\ufa9c', &['\u716e']), ('\ufa9d', &['\u77a7']), ('\ufa9e', &['\u7235']), ('\ufa9f',
+ &['\u72af']), ('\ufaa0', &['\u732a']), ('\ufaa1', &['\u7471']), ('\ufaa2', &['\u7506']),
+ ('\ufaa3', &['\u753b']), ('\ufaa4', &['\u761d']), ('\ufaa5', &['\u761f']), ('\ufaa6',
+ &['\u76ca']), ('\ufaa7', &['\u76db']), ('\ufaa8', &['\u76f4']), ('\ufaa9', &['\u774a']),
+ ('\ufaaa', &['\u7740']), ('\ufaab', &['\u78cc']), ('\ufaac', &['\u7ab1']), ('\ufaad',
+ &['\u7bc0']), ('\ufaae', &['\u7c7b']), ('\ufaaf', &['\u7d5b']), ('\ufab0', &['\u7df4']),
+ ('\ufab1', &['\u7f3e']), ('\ufab2', &['\u8005']), ('\ufab3', &['\u8352']), ('\ufab4',
+ &['\u83ef']), ('\ufab5', &['\u8779']), ('\ufab6', &['\u8941']), ('\ufab7', &['\u8986']),
+ ('\ufab8', &['\u8996']), ('\ufab9', &['\u8abf']), ('\ufaba', &['\u8af8']), ('\ufabb',
+ &['\u8acb']), ('\ufabc', &['\u8b01']), ('\ufabd', &['\u8afe']), ('\ufabe', &['\u8aed']),
+ ('\ufabf', &['\u8b39']), ('\ufac0', &['\u8b8a']), ('\ufac1', &['\u8d08']), ('\ufac2',
+ &['\u8f38']), ('\ufac3', &['\u9072']), ('\ufac4', &['\u9199']), ('\ufac5', &['\u9276']),
+ ('\ufac6', &['\u967c']), ('\ufac7', &['\u96e3']), ('\ufac8', &['\u9756']), ('\ufac9',
+ &['\u97db']), ('\ufaca', &['\u97ff']), ('\ufacb', &['\u980b']), ('\ufacc', &['\u983b']),
+ ('\ufacd', &['\u9b12']), ('\uface', &['\u9f9c']), ('\ufacf', &['\U0002284a']), ('\ufad0',
+ &['\U00022844']), ('\ufad1', &['\U000233d5']), ('\ufad2', &['\u3b9d']), ('\ufad3',
+ &['\u4018']), ('\ufad4', &['\u4039']), ('\ufad5', &['\U00025249']), ('\ufad6',
+ &['\U00025cd0']), ('\ufad7', &['\U00027ed3']), ('\ufad8', &['\u9f43']), ('\ufad9',
+ &['\u9f8e']), ('\ufb1d', &['\u05d9', '\u05b4']), ('\ufb1f', &['\u05f2', '\u05b7']),
+ ('\ufb2a', &['\u05e9', '\u05c1']), ('\ufb2b', &['\u05e9', '\u05c2']), ('\ufb2c', &['\ufb49',
+ '\u05c1']), ('\ufb2d', &['\ufb49', '\u05c2']), ('\ufb2e', &['\u05d0', '\u05b7']), ('\ufb2f',
+ &['\u05d0', '\u05b8']), ('\ufb30', &['\u05d0', '\u05bc']), ('\ufb31', &['\u05d1',
+ '\u05bc']), ('\ufb32', &['\u05d2', '\u05bc']), ('\ufb33', &['\u05d3', '\u05bc']), ('\ufb34',
+ &['\u05d4', '\u05bc']), ('\ufb35', &['\u05d5', '\u05bc']), ('\ufb36', &['\u05d6',
+ '\u05bc']), ('\ufb38', &['\u05d8', '\u05bc']), ('\ufb39', &['\u05d9', '\u05bc']), ('\ufb3a',
+ &['\u05da', '\u05bc']), ('\ufb3b', &['\u05db', '\u05bc']), ('\ufb3c', &['\u05dc',
+ '\u05bc']), ('\ufb3e', &['\u05de', '\u05bc']), ('\ufb40', &['\u05e0', '\u05bc']), ('\ufb41',
+ &['\u05e1', '\u05bc']), ('\ufb43', &['\u05e3', '\u05bc']), ('\ufb44', &['\u05e4',
+ '\u05bc']), ('\ufb46', &['\u05e6', '\u05bc']), ('\ufb47', &['\u05e7', '\u05bc']), ('\ufb48',
+ &['\u05e8', '\u05bc']), ('\ufb49', &['\u05e9', '\u05bc']), ('\ufb4a', &['\u05ea',
+ '\u05bc']), ('\ufb4b', &['\u05d5', '\u05b9']), ('\ufb4c', &['\u05d1', '\u05bf']), ('\ufb4d',
+ &['\u05db', '\u05bf']), ('\ufb4e', &['\u05e4', '\u05bf']), ('\U0001109a', &['\U00011099',
+ '\U000110ba']), ('\U0001109c', &['\U0001109b', '\U000110ba']), ('\U000110ab',
+ &['\U000110a5', '\U000110ba']), ('\U0001112e', &['\U00011131', '\U00011127']),
+ ('\U0001112f', &['\U00011132', '\U00011127']), ('\U0001134b', &['\U00011347',
+ '\U0001133e']), ('\U0001134c', &['\U00011347', '\U00011357']), ('\U000114bb',
+ &['\U000114b9', '\U000114ba']), ('\U000114bc', &['\U000114b9', '\U000114b0']),
+ ('\U000114be', &['\U000114b9', '\U000114bd']), ('\U000115ba', &['\U000115b8',
+ '\U000115af']), ('\U000115bb', &['\U000115b9', '\U000115af']), ('\U0001d15e',
+ &['\U0001d157', '\U0001d165']), ('\U0001d15f', &['\U0001d158', '\U0001d165']),
+ ('\U0001d160', &['\U0001d15f', '\U0001d16e']), ('\U0001d161', &['\U0001d15f',
+ '\U0001d16f']), ('\U0001d162', &['\U0001d15f', '\U0001d170']), ('\U0001d163',
+ &['\U0001d15f', '\U0001d171']), ('\U0001d164', &['\U0001d15f', '\U0001d172']),
+ ('\U0001d1bb', &['\U0001d1b9', '\U0001d165']), ('\U0001d1bc', &['\U0001d1ba',
+ '\U0001d165']), ('\U0001d1bd', &['\U0001d1bb', '\U0001d16e']), ('\U0001d1be',
+ &['\U0001d1bc', '\U0001d16e']), ('\U0001d1bf', &['\U0001d1bb', '\U0001d16f']),
+ ('\U0001d1c0', &['\U0001d1bc', '\U0001d16f']), ('\U0002f800', &['\u4e3d']), ('\U0002f801',
+ &['\u4e38']), ('\U0002f802', &['\u4e41']), ('\U0002f803', &['\U00020122']), ('\U0002f804',
+ &['\u4f60']), ('\U0002f805', &['\u4fae']), ('\U0002f806', &['\u4fbb']), ('\U0002f807',
+ &['\u5002']), ('\U0002f808', &['\u507a']), ('\U0002f809', &['\u5099']), ('\U0002f80a',
+ &['\u50e7']), ('\U0002f80b', &['\u50cf']), ('\U0002f80c', &['\u349e']), ('\U0002f80d',
+ &['\U0002063a']), ('\U0002f80e', &['\u514d']), ('\U0002f80f', &['\u5154']), ('\U0002f810',
+ &['\u5164']), ('\U0002f811', &['\u5177']), ('\U0002f812', &['\U0002051c']), ('\U0002f813',
+ &['\u34b9']), ('\U0002f814', &['\u5167']), ('\U0002f815', &['\u518d']), ('\U0002f816',
+ &['\U0002054b']), ('\U0002f817', &['\u5197']), ('\U0002f818', &['\u51a4']), ('\U0002f819',
+ &['\u4ecc']), ('\U0002f81a', &['\u51ac']), ('\U0002f81b', &['\u51b5']), ('\U0002f81c',
+ &['\U000291df']), ('\U0002f81d', &['\u51f5']), ('\U0002f81e', &['\u5203']), ('\U0002f81f',
+ &['\u34df']), ('\U0002f820', &['\u523b']), ('\U0002f821', &['\u5246']), ('\U0002f822',
+ &['\u5272']), ('\U0002f823', &['\u5277']), ('\U0002f824', &['\u3515']), ('\U0002f825',
+ &['\u52c7']), ('\U0002f826', &['\u52c9']), ('\U0002f827', &['\u52e4']), ('\U0002f828',
+ &['\u52fa']), ('\U0002f829', &['\u5305']), ('\U0002f82a', &['\u5306']), ('\U0002f82b',
+ &['\u5317']), ('\U0002f82c', &['\u5349']), ('\U0002f82d', &['\u5351']), ('\U0002f82e',
+ &['\u535a']), ('\U0002f82f', &['\u5373']), ('\U0002f830', &['\u537d']), ('\U0002f831',
+ &['\u537f']), ('\U0002f832', &['\u537f']), ('\U0002f833', &['\u537f']), ('\U0002f834',
+ &['\U00020a2c']), ('\U0002f835', &['\u7070']), ('\U0002f836', &['\u53ca']), ('\U0002f837',
+ &['\u53df']), ('\U0002f838', &['\U00020b63']), ('\U0002f839', &['\u53eb']), ('\U0002f83a',
+ &['\u53f1']), ('\U0002f83b', &['\u5406']), ('\U0002f83c', &['\u549e']), ('\U0002f83d',
+ &['\u5438']), ('\U0002f83e', &['\u5448']), ('\U0002f83f', &['\u5468']), ('\U0002f840',
+ &['\u54a2']), ('\U0002f841', &['\u54f6']), ('\U0002f842', &['\u5510']), ('\U0002f843',
+ &['\u5553']), ('\U0002f844', &['\u5563']), ('\U0002f845', &['\u5584']), ('\U0002f846',
+ &['\u5584']), ('\U0002f847', &['\u5599']), ('\U0002f848', &['\u55ab']), ('\U0002f849',
+ &['\u55b3']), ('\U0002f84a', &['\u55c2']), ('\U0002f84b', &['\u5716']), ('\U0002f84c',
+ &['\u5606']), ('\U0002f84d', &['\u5717']), ('\U0002f84e', &['\u5651']), ('\U0002f84f',
+ &['\u5674']), ('\U0002f850', &['\u5207']), ('\U0002f851', &['\u58ee']), ('\U0002f852',
+ &['\u57ce']), ('\U0002f853', &['\u57f4']), ('\U0002f854', &['\u580d']), ('\U0002f855',
+ &['\u578b']), ('\U0002f856', &['\u5832']), ('\U0002f857', &['\u5831']), ('\U0002f858',
+ &['\u58ac']), ('\U0002f859', &['\U000214e4']), ('\U0002f85a', &['\u58f2']), ('\U0002f85b',
+ &['\u58f7']), ('\U0002f85c', &['\u5906']), ('\U0002f85d', &['\u591a']), ('\U0002f85e',
+ &['\u5922']), ('\U0002f85f', &['\u5962']), ('\U0002f860', &['\U000216a8']), ('\U0002f861',
+ &['\U000216ea']), ('\U0002f862', &['\u59ec']), ('\U0002f863', &['\u5a1b']), ('\U0002f864',
+ &['\u5a27']), ('\U0002f865', &['\u59d8']), ('\U0002f866', &['\u5a66']), ('\U0002f867',
+ &['\u36ee']), ('\U0002f868', &['\u36fc']), ('\U0002f869', &['\u5b08']), ('\U0002f86a',
+ &['\u5b3e']), ('\U0002f86b', &['\u5b3e']), ('\U0002f86c', &['\U000219c8']), ('\U0002f86d',
+ &['\u5bc3']), ('\U0002f86e', &['\u5bd8']), ('\U0002f86f', &['\u5be7']), ('\U0002f870',
+ &['\u5bf3']), ('\U0002f871', &['\U00021b18']), ('\U0002f872', &['\u5bff']), ('\U0002f873',
+ &['\u5c06']), ('\U0002f874', &['\u5f53']), ('\U0002f875', &['\u5c22']), ('\U0002f876',
+ &['\u3781']), ('\U0002f877', &['\u5c60']), ('\U0002f878', &['\u5c6e']), ('\U0002f879',
+ &['\u5cc0']), ('\U0002f87a', &['\u5c8d']), ('\U0002f87b', &['\U00021de4']), ('\U0002f87c',
+ &['\u5d43']), ('\U0002f87d', &['\U00021de6']), ('\U0002f87e', &['\u5d6e']), ('\U0002f87f',
+ &['\u5d6b']), ('\U0002f880', &['\u5d7c']), ('\U0002f881', &['\u5de1']), ('\U0002f882',
+ &['\u5de2']), ('\U0002f883', &['\u382f']), ('\U0002f884', &['\u5dfd']), ('\U0002f885',
+ &['\u5e28']), ('\U0002f886', &['\u5e3d']), ('\U0002f887', &['\u5e69']), ('\U0002f888',
+ &['\u3862']), ('\U0002f889', &['\U00022183']), ('\U0002f88a', &['\u387c']), ('\U0002f88b',
+ &['\u5eb0']), ('\U0002f88c', &['\u5eb3']), ('\U0002f88d', &['\u5eb6']), ('\U0002f88e',
+ &['\u5eca']), ('\U0002f88f', &['\U0002a392']), ('\U0002f890', &['\u5efe']), ('\U0002f891',
+ &['\U00022331']), ('\U0002f892', &['\U00022331']), ('\U0002f893', &['\u8201']),
+ ('\U0002f894', &['\u5f22']), ('\U0002f895', &['\u5f22']), ('\U0002f896', &['\u38c7']),
+ ('\U0002f897', &['\U000232b8']), ('\U0002f898', &['\U000261da']), ('\U0002f899',
+ &['\u5f62']), ('\U0002f89a', &['\u5f6b']), ('\U0002f89b', &['\u38e3']), ('\U0002f89c',
+ &['\u5f9a']), ('\U0002f89d', &['\u5fcd']), ('\U0002f89e', &['\u5fd7']), ('\U0002f89f',
+ &['\u5ff9']), ('\U0002f8a0', &['\u6081']), ('\U0002f8a1', &['\u393a']), ('\U0002f8a2',
+ &['\u391c']), ('\U0002f8a3', &['\u6094']), ('\U0002f8a4', &['\U000226d4']), ('\U0002f8a5',
+ &['\u60c7']), ('\U0002f8a6', &['\u6148']), ('\U0002f8a7', &['\u614c']), ('\U0002f8a8',
+ &['\u614e']), ('\U0002f8a9', &['\u614c']), ('\U0002f8aa', &['\u617a']), ('\U0002f8ab',
+ &['\u618e']), ('\U0002f8ac', &['\u61b2']), ('\U0002f8ad', &['\u61a4']), ('\U0002f8ae',
+ &['\u61af']), ('\U0002f8af', &['\u61de']), ('\U0002f8b0', &['\u61f2']), ('\U0002f8b1',
+ &['\u61f6']), ('\U0002f8b2', &['\u6210']), ('\U0002f8b3', &['\u621b']), ('\U0002f8b4',
+ &['\u625d']), ('\U0002f8b5', &['\u62b1']), ('\U0002f8b6', &['\u62d4']), ('\U0002f8b7',
+ &['\u6350']), ('\U0002f8b8', &['\U00022b0c']), ('\U0002f8b9', &['\u633d']), ('\U0002f8ba',
+ &['\u62fc']), ('\U0002f8bb', &['\u6368']), ('\U0002f8bc', &['\u6383']), ('\U0002f8bd',
+ &['\u63e4']), ('\U0002f8be', &['\U00022bf1']), ('\U0002f8bf', &['\u6422']), ('\U0002f8c0',
+ &['\u63c5']), ('\U0002f8c1', &['\u63a9']), ('\U0002f8c2', &['\u3a2e']), ('\U0002f8c3',
+ &['\u6469']), ('\U0002f8c4', &['\u647e']), ('\U0002f8c5', &['\u649d']), ('\U0002f8c6',
+ &['\u6477']), ('\U0002f8c7', &['\u3a6c']), ('\U0002f8c8', &['\u654f']), ('\U0002f8c9',
+ &['\u656c']), ('\U0002f8ca', &['\U0002300a']), ('\U0002f8cb', &['\u65e3']), ('\U0002f8cc',
+ &['\u66f8']), ('\U0002f8cd', &['\u6649']), ('\U0002f8ce', &['\u3b19']), ('\U0002f8cf',
+ &['\u6691']), ('\U0002f8d0', &['\u3b08']), ('\U0002f8d1', &['\u3ae4']), ('\U0002f8d2',
+ &['\u5192']), ('\U0002f8d3', &['\u5195']), ('\U0002f8d4', &['\u6700']), ('\U0002f8d5',
+ &['\u669c']), ('\U0002f8d6', &['\u80ad']), ('\U0002f8d7', &['\u43d9']), ('\U0002f8d8',
+ &['\u6717']), ('\U0002f8d9', &['\u671b']), ('\U0002f8da', &['\u6721']), ('\U0002f8db',
+ &['\u675e']), ('\U0002f8dc', &['\u6753']), ('\U0002f8dd', &['\U000233c3']), ('\U0002f8de',
+ &['\u3b49']), ('\U0002f8df', &['\u67fa']), ('\U0002f8e0', &['\u6785']), ('\U0002f8e1',
+ &['\u6852']), ('\U0002f8e2', &['\u6885']), ('\U0002f8e3', &['\U0002346d']), ('\U0002f8e4',
+ &['\u688e']), ('\U0002f8e5', &['\u681f']), ('\U0002f8e6', &['\u6914']), ('\U0002f8e7',
+ &['\u3b9d']), ('\U0002f8e8', &['\u6942']), ('\U0002f8e9', &['\u69a3']), ('\U0002f8ea',
+ &['\u69ea']), ('\U0002f8eb', &['\u6aa8']), ('\U0002f8ec', &['\U000236a3']), ('\U0002f8ed',
+ &['\u6adb']), ('\U0002f8ee', &['\u3c18']), ('\U0002f8ef', &['\u6b21']), ('\U0002f8f0',
+ &['\U000238a7']), ('\U0002f8f1', &['\u6b54']), ('\U0002f8f2', &['\u3c4e']), ('\U0002f8f3',
+ &['\u6b72']), ('\U0002f8f4', &['\u6b9f']), ('\U0002f8f5', &['\u6bba']), ('\U0002f8f6',
+ &['\u6bbb']), ('\U0002f8f7', &['\U00023a8d']), ('\U0002f8f8', &['\U00021d0b']),
+ ('\U0002f8f9', &['\U00023afa']), ('\U0002f8fa', &['\u6c4e']), ('\U0002f8fb',
+ &['\U00023cbc']), ('\U0002f8fc', &['\u6cbf']), ('\U0002f8fd', &['\u6ccd']), ('\U0002f8fe',
+ &['\u6c67']), ('\U0002f8ff', &['\u6d16']), ('\U0002f900', &['\u6d3e']), ('\U0002f901',
+ &['\u6d77']), ('\U0002f902', &['\u6d41']), ('\U0002f903', &['\u6d69']), ('\U0002f904',
+ &['\u6d78']), ('\U0002f905', &['\u6d85']), ('\U0002f906', &['\U00023d1e']), ('\U0002f907',
+ &['\u6d34']), ('\U0002f908', &['\u6e2f']), ('\U0002f909', &['\u6e6e']), ('\U0002f90a',
+ &['\u3d33']), ('\U0002f90b', &['\u6ecb']), ('\U0002f90c', &['\u6ec7']), ('\U0002f90d',
+ &['\U00023ed1']), ('\U0002f90e', &['\u6df9']), ('\U0002f90f', &['\u6f6e']), ('\U0002f910',
+ &['\U00023f5e']), ('\U0002f911', &['\U00023f8e']), ('\U0002f912', &['\u6fc6']),
+ ('\U0002f913', &['\u7039']), ('\U0002f914', &['\u701e']), ('\U0002f915', &['\u701b']),
+ ('\U0002f916', &['\u3d96']), ('\U0002f917', &['\u704a']), ('\U0002f918', &['\u707d']),
+ ('\U0002f919', &['\u7077']), ('\U0002f91a', &['\u70ad']), ('\U0002f91b', &['\U00020525']),
+ ('\U0002f91c', &['\u7145']), ('\U0002f91d', &['\U00024263']), ('\U0002f91e', &['\u719c']),
+ ('\U0002f91f', &['\U000243ab']), ('\U0002f920', &['\u7228']), ('\U0002f921', &['\u7235']),
+ ('\U0002f922', &['\u7250']), ('\U0002f923', &['\U00024608']), ('\U0002f924', &['\u7280']),
+ ('\U0002f925', &['\u7295']), ('\U0002f926', &['\U00024735']), ('\U0002f927',
+ &['\U00024814']), ('\U0002f928', &['\u737a']), ('\U0002f929', &['\u738b']), ('\U0002f92a',
+ &['\u3eac']), ('\U0002f92b', &['\u73a5']), ('\U0002f92c', &['\u3eb8']), ('\U0002f92d',
+ &['\u3eb8']), ('\U0002f92e', &['\u7447']), ('\U0002f92f', &['\u745c']), ('\U0002f930',
+ &['\u7471']), ('\U0002f931', &['\u7485']), ('\U0002f932', &['\u74ca']), ('\U0002f933',
+ &['\u3f1b']), ('\U0002f934', &['\u7524']), ('\U0002f935', &['\U00024c36']), ('\U0002f936',
+ &['\u753e']), ('\U0002f937', &['\U00024c92']), ('\U0002f938', &['\u7570']), ('\U0002f939',
+ &['\U0002219f']), ('\U0002f93a', &['\u7610']), ('\U0002f93b', &['\U00024fa1']),
+ ('\U0002f93c', &['\U00024fb8']), ('\U0002f93d', &['\U00025044']), ('\U0002f93e',
+ &['\u3ffc']), ('\U0002f93f', &['\u4008']), ('\U0002f940', &['\u76f4']), ('\U0002f941',
+ &['\U000250f3']), ('\U0002f942', &['\U000250f2']), ('\U0002f943', &['\U00025119']),
+ ('\U0002f944', &['\U00025133']), ('\U0002f945', &['\u771e']), ('\U0002f946', &['\u771f']),
+ ('\U0002f947', &['\u771f']), ('\U0002f948', &['\u774a']), ('\U0002f949', &['\u4039']),
+ ('\U0002f94a', &['\u778b']), ('\U0002f94b', &['\u4046']), ('\U0002f94c', &['\u4096']),
+ ('\U0002f94d', &['\U0002541d']), ('\U0002f94e', &['\u784e']), ('\U0002f94f', &['\u788c']),
+ ('\U0002f950', &['\u78cc']), ('\U0002f951', &['\u40e3']), ('\U0002f952', &['\U00025626']),
+ ('\U0002f953', &['\u7956']), ('\U0002f954', &['\U0002569a']), ('\U0002f955',
+ &['\U000256c5']), ('\U0002f956', &['\u798f']), ('\U0002f957', &['\u79eb']), ('\U0002f958',
+ &['\u412f']), ('\U0002f959', &['\u7a40']), ('\U0002f95a', &['\u7a4a']), ('\U0002f95b',
+ &['\u7a4f']), ('\U0002f95c', &['\U0002597c']), ('\U0002f95d', &['\U00025aa7']),
+ ('\U0002f95e', &['\U00025aa7']), ('\U0002f95f', &['\u7aee']), ('\U0002f960', &['\u4202']),
+ ('\U0002f961', &['\U00025bab']), ('\U0002f962', &['\u7bc6']), ('\U0002f963', &['\u7bc9']),
+ ('\U0002f964', &['\u4227']), ('\U0002f965', &['\U00025c80']), ('\U0002f966', &['\u7cd2']),
+ ('\U0002f967', &['\u42a0']), ('\U0002f968', &['\u7ce8']), ('\U0002f969', &['\u7ce3']),
+ ('\U0002f96a', &['\u7d00']), ('\U0002f96b', &['\U00025f86']), ('\U0002f96c', &['\u7d63']),
+ ('\U0002f96d', &['\u4301']), ('\U0002f96e', &['\u7dc7']), ('\U0002f96f', &['\u7e02']),
+ ('\U0002f970', &['\u7e45']), ('\U0002f971', &['\u4334']), ('\U0002f972', &['\U00026228']),
+ ('\U0002f973', &['\U00026247']), ('\U0002f974', &['\u4359']), ('\U0002f975',
+ &['\U000262d9']), ('\U0002f976', &['\u7f7a']), ('\U0002f977', &['\U0002633e']),
+ ('\U0002f978', &['\u7f95']), ('\U0002f979', &['\u7ffa']), ('\U0002f97a', &['\u8005']),
+ ('\U0002f97b', &['\U000264da']), ('\U0002f97c', &['\U00026523']), ('\U0002f97d',
+ &['\u8060']), ('\U0002f97e', &['\U000265a8']), ('\U0002f97f', &['\u8070']), ('\U0002f980',
+ &['\U0002335f']), ('\U0002f981', &['\u43d5']), ('\U0002f982', &['\u80b2']), ('\U0002f983',
+ &['\u8103']), ('\U0002f984', &['\u440b']), ('\U0002f985', &['\u813e']), ('\U0002f986',
+ &['\u5ab5']), ('\U0002f987', &['\U000267a7']), ('\U0002f988', &['\U000267b5']),
+ ('\U0002f989', &['\U00023393']), ('\U0002f98a', &['\U0002339c']), ('\U0002f98b',
+ &['\u8201']), ('\U0002f98c', &['\u8204']), ('\U0002f98d', &['\u8f9e']), ('\U0002f98e',
+ &['\u446b']), ('\U0002f98f', &['\u8291']), ('\U0002f990', &['\u828b']), ('\U0002f991',
+ &['\u829d']), ('\U0002f992', &['\u52b3']), ('\U0002f993', &['\u82b1']), ('\U0002f994',
+ &['\u82b3']), ('\U0002f995', &['\u82bd']), ('\U0002f996', &['\u82e6']), ('\U0002f997',
+ &['\U00026b3c']), ('\U0002f998', &['\u82e5']), ('\U0002f999', &['\u831d']), ('\U0002f99a',
+ &['\u8363']), ('\U0002f99b', &['\u83ad']), ('\U0002f99c', &['\u8323']), ('\U0002f99d',
+ &['\u83bd']), ('\U0002f99e', &['\u83e7']), ('\U0002f99f', &['\u8457']), ('\U0002f9a0',
+ &['\u8353']), ('\U0002f9a1', &['\u83ca']), ('\U0002f9a2', &['\u83cc']), ('\U0002f9a3',
+ &['\u83dc']), ('\U0002f9a4', &['\U00026c36']), ('\U0002f9a5', &['\U00026d6b']),
+ ('\U0002f9a6', &['\U00026cd5']), ('\U0002f9a7', &['\u452b']), ('\U0002f9a8', &['\u84f1']),
+ ('\U0002f9a9', &['\u84f3']), ('\U0002f9aa', &['\u8516']), ('\U0002f9ab', &['\U000273ca']),
+ ('\U0002f9ac', &['\u8564']), ('\U0002f9ad', &['\U00026f2c']), ('\U0002f9ae', &['\u455d']),
+ ('\U0002f9af', &['\u4561']), ('\U0002f9b0', &['\U00026fb1']), ('\U0002f9b1',
+ &['\U000270d2']), ('\U0002f9b2', &['\u456b']), ('\U0002f9b3', &['\u8650']), ('\U0002f9b4',
+ &['\u865c']), ('\U0002f9b5', &['\u8667']), ('\U0002f9b6', &['\u8669']), ('\U0002f9b7',
+ &['\u86a9']), ('\U0002f9b8', &['\u8688']), ('\U0002f9b9', &['\u870e']), ('\U0002f9ba',
+ &['\u86e2']), ('\U0002f9bb', &['\u8779']), ('\U0002f9bc', &['\u8728']), ('\U0002f9bd',
+ &['\u876b']), ('\U0002f9be', &['\u8786']), ('\U0002f9bf', &['\u45d7']), ('\U0002f9c0',
+ &['\u87e1']), ('\U0002f9c1', &['\u8801']), ('\U0002f9c2', &['\u45f9']), ('\U0002f9c3',
+ &['\u8860']), ('\U0002f9c4', &['\u8863']), ('\U0002f9c5', &['\U00027667']), ('\U0002f9c6',
+ &['\u88d7']), ('\U0002f9c7', &['\u88de']), ('\U0002f9c8', &['\u4635']), ('\U0002f9c9',
+ &['\u88fa']), ('\U0002f9ca', &['\u34bb']), ('\U0002f9cb', &['\U000278ae']), ('\U0002f9cc',
+ &['\U00027966']), ('\U0002f9cd', &['\u46be']), ('\U0002f9ce', &['\u46c7']), ('\U0002f9cf',
+ &['\u8aa0']), ('\U0002f9d0', &['\u8aed']), ('\U0002f9d1', &['\u8b8a']), ('\U0002f9d2',
+ &['\u8c55']), ('\U0002f9d3', &['\U00027ca8']), ('\U0002f9d4', &['\u8cab']), ('\U0002f9d5',
+ &['\u8cc1']), ('\U0002f9d6', &['\u8d1b']), ('\U0002f9d7', &['\u8d77']), ('\U0002f9d8',
+ &['\U00027f2f']), ('\U0002f9d9', &['\U00020804']), ('\U0002f9da', &['\u8dcb']),
+ ('\U0002f9db', &['\u8dbc']), ('\U0002f9dc', &['\u8df0']), ('\U0002f9dd', &['\U000208de']),
+ ('\U0002f9de', &['\u8ed4']), ('\U0002f9df', &['\u8f38']), ('\U0002f9e0', &['\U000285d2']),
+ ('\U0002f9e1', &['\U000285ed']), ('\U0002f9e2', &['\u9094']), ('\U0002f9e3', &['\u90f1']),
+ ('\U0002f9e4', &['\u9111']), ('\U0002f9e5', &['\U0002872e']), ('\U0002f9e6', &['\u911b']),
+ ('\U0002f9e7', &['\u9238']), ('\U0002f9e8', &['\u92d7']), ('\U0002f9e9', &['\u92d8']),
+ ('\U0002f9ea', &['\u927c']), ('\U0002f9eb', &['\u93f9']), ('\U0002f9ec', &['\u9415']),
+ ('\U0002f9ed', &['\U00028bfa']), ('\U0002f9ee', &['\u958b']), ('\U0002f9ef', &['\u4995']),
+ ('\U0002f9f0', &['\u95b7']), ('\U0002f9f1', &['\U00028d77']), ('\U0002f9f2', &['\u49e6']),
+ ('\U0002f9f3', &['\u96c3']), ('\U0002f9f4', &['\u5db2']), ('\U0002f9f5', &['\u9723']),
+ ('\U0002f9f6', &['\U00029145']), ('\U0002f9f7', &['\U0002921a']), ('\U0002f9f8',
+ &['\u4a6e']), ('\U0002f9f9', &['\u4a76']), ('\U0002f9fa', &['\u97e0']), ('\U0002f9fb',
+ &['\U0002940a']), ('\U0002f9fc', &['\u4ab2']), ('\U0002f9fd', &['\U00029496']),
+ ('\U0002f9fe', &['\u980b']), ('\U0002f9ff', &['\u980b']), ('\U0002fa00', &['\u9829']),
+ ('\U0002fa01', &['\U000295b6']), ('\U0002fa02', &['\u98e2']), ('\U0002fa03', &['\u4b33']),
+ ('\U0002fa04', &['\u9929']), ('\U0002fa05', &['\u99a7']), ('\U0002fa06', &['\u99c2']),
+ ('\U0002fa07', &['\u99fe']), ('\U0002fa08', &['\u4bce']), ('\U0002fa09', &['\U00029b30']),
+ ('\U0002fa0a', &['\u9b12']), ('\U0002fa0b', &['\u9c40']), ('\U0002fa0c', &['\u9cfd']),
+ ('\U0002fa0d', &['\u4cce']), ('\U0002fa0e', &['\u4ced']), ('\U0002fa0f', &['\u9d67']),
+ ('\U0002fa10', &['\U0002a0ce']), ('\U0002fa11', &['\u4cf8']), ('\U0002fa12',
+ &['\U0002a105']), ('\U0002fa13', &['\U0002a20e']), ('\U0002fa14', &['\U0002a291']),
+ ('\U0002fa15', &['\u9ebb']), ('\U0002fa16', &['\u4d56']), ('\U0002fa17', &['\u9ef9']),
+ ('\U0002fa18', &['\u9efe']), ('\U0002fa19', &['\u9f05']), ('\U0002fa1a', &['\u9f0f']),
+ ('\U0002fa1b', &['\u9f16']), ('\U0002fa1c', &['\u9f3b']), ('\U0002fa1d', &['\U0002a600'])
+ ];
+
+ // Compatibility decompositions
+ pub static compatibility_table: &'static [(char, &'static [char])] = &[
+ ('\xa0', &['\x20']), ('\xa8', &['\x20', '\u0308']), ('\xaa', &['\x61']), ('\xaf', &['\x20',
+ '\u0304']), ('\xb2', &['\x32']), ('\xb3', &['\x33']), ('\xb4', &['\x20', '\u0301']),
+ ('\xb5', &['\u03bc']), ('\xb8', &['\x20', '\u0327']), ('\xb9', &['\x31']), ('\xba',
+ &['\x6f']), ('\xbc', &['\x31', '\u2044', '\x34']), ('\xbd', &['\x31', '\u2044', '\x32']),
+ ('\xbe', &['\x33', '\u2044', '\x34']), ('\u0132', &['\x49', '\x4a']), ('\u0133', &['\x69',
+ '\x6a']), ('\u013f', &['\x4c', '\xb7']), ('\u0140', &['\x6c', '\xb7']), ('\u0149',
+ &['\u02bc', '\x6e']), ('\u017f', &['\x73']), ('\u01c4', &['\x44', '\u017d']), ('\u01c5',
+ &['\x44', '\u017e']), ('\u01c6', &['\x64', '\u017e']), ('\u01c7', &['\x4c', '\x4a']),
+ ('\u01c8', &['\x4c', '\x6a']), ('\u01c9', &['\x6c', '\x6a']), ('\u01ca', &['\x4e', '\x4a']),
+ ('\u01cb', &['\x4e', '\x6a']), ('\u01cc', &['\x6e', '\x6a']), ('\u01f1', &['\x44', '\x5a']),
+ ('\u01f2', &['\x44', '\x7a']), ('\u01f3', &['\x64', '\x7a']), ('\u02b0', &['\x68']),
+ ('\u02b1', &['\u0266']), ('\u02b2', &['\x6a']), ('\u02b3', &['\x72']), ('\u02b4',
+ &['\u0279']), ('\u02b5', &['\u027b']), ('\u02b6', &['\u0281']), ('\u02b7', &['\x77']),
+ ('\u02b8', &['\x79']), ('\u02d8', &['\x20', '\u0306']), ('\u02d9', &['\x20', '\u0307']),
+ ('\u02da', &['\x20', '\u030a']), ('\u02db', &['\x20', '\u0328']), ('\u02dc', &['\x20',
+ '\u0303']), ('\u02dd', &['\x20', '\u030b']), ('\u02e0', &['\u0263']), ('\u02e1', &['\x6c']),
+ ('\u02e2', &['\x73']), ('\u02e3', &['\x78']), ('\u02e4', &['\u0295']), ('\u037a', &['\x20',
+ '\u0345']), ('\u0384', &['\x20', '\u0301']), ('\u03d0', &['\u03b2']), ('\u03d1',
+ &['\u03b8']), ('\u03d2', &['\u03a5']), ('\u03d5', &['\u03c6']), ('\u03d6', &['\u03c0']),
+ ('\u03f0', &['\u03ba']), ('\u03f1', &['\u03c1']), ('\u03f2', &['\u03c2']), ('\u03f4',
+ &['\u0398']), ('\u03f5', &['\u03b5']), ('\u03f9', &['\u03a3']), ('\u0587', &['\u0565',
+ '\u0582']), ('\u0675', &['\u0627', '\u0674']), ('\u0676', &['\u0648', '\u0674']), ('\u0677',
+ &['\u06c7', '\u0674']), ('\u0678', &['\u064a', '\u0674']), ('\u0e33', &['\u0e4d',
+ '\u0e32']), ('\u0eb3', &['\u0ecd', '\u0eb2']), ('\u0edc', &['\u0eab', '\u0e99']), ('\u0edd',
+ &['\u0eab', '\u0ea1']), ('\u0f0c', &['\u0f0b']), ('\u0f77', &['\u0fb2', '\u0f81']),
+ ('\u0f79', &['\u0fb3', '\u0f81']), ('\u10fc', &['\u10dc']), ('\u1d2c', &['\x41']),
+ ('\u1d2d', &['\xc6']), ('\u1d2e', &['\x42']), ('\u1d30', &['\x44']), ('\u1d31', &['\x45']),
+ ('\u1d32', &['\u018e']), ('\u1d33', &['\x47']), ('\u1d34', &['\x48']), ('\u1d35',
+ &['\x49']), ('\u1d36', &['\x4a']), ('\u1d37', &['\x4b']), ('\u1d38', &['\x4c']), ('\u1d39',
+ &['\x4d']), ('\u1d3a', &['\x4e']), ('\u1d3c', &['\x4f']), ('\u1d3d', &['\u0222']),
+ ('\u1d3e', &['\x50']), ('\u1d3f', &['\x52']), ('\u1d40', &['\x54']), ('\u1d41', &['\x55']),
+ ('\u1d42', &['\x57']), ('\u1d43', &['\x61']), ('\u1d44', &['\u0250']), ('\u1d45',
+ &['\u0251']), ('\u1d46', &['\u1d02']), ('\u1d47', &['\x62']), ('\u1d48', &['\x64']),
+ ('\u1d49', &['\x65']), ('\u1d4a', &['\u0259']), ('\u1d4b', &['\u025b']), ('\u1d4c',
+ &['\u025c']), ('\u1d4d', &['\x67']), ('\u1d4f', &['\x6b']), ('\u1d50', &['\x6d']),
+ ('\u1d51', &['\u014b']), ('\u1d52', &['\x6f']), ('\u1d53', &['\u0254']), ('\u1d54',
+ &['\u1d16']), ('\u1d55', &['\u1d17']), ('\u1d56', &['\x70']), ('\u1d57', &['\x74']),
+ ('\u1d58', &['\x75']), ('\u1d59', &['\u1d1d']), ('\u1d5a', &['\u026f']), ('\u1d5b',
+ &['\x76']), ('\u1d5c', &['\u1d25']), ('\u1d5d', &['\u03b2']), ('\u1d5e', &['\u03b3']),
+ ('\u1d5f', &['\u03b4']), ('\u1d60', &['\u03c6']), ('\u1d61', &['\u03c7']), ('\u1d62',
+ &['\x69']), ('\u1d63', &['\x72']), ('\u1d64', &['\x75']), ('\u1d65', &['\x76']), ('\u1d66',
+ &['\u03b2']), ('\u1d67', &['\u03b3']), ('\u1d68', &['\u03c1']), ('\u1d69', &['\u03c6']),
+ ('\u1d6a', &['\u03c7']), ('\u1d78', &['\u043d']), ('\u1d9b', &['\u0252']), ('\u1d9c',
+ &['\x63']), ('\u1d9d', &['\u0255']), ('\u1d9e', &['\xf0']), ('\u1d9f', &['\u025c']),
+ ('\u1da0', &['\x66']), ('\u1da1', &['\u025f']), ('\u1da2', &['\u0261']), ('\u1da3',
+ &['\u0265']), ('\u1da4', &['\u0268']), ('\u1da5', &['\u0269']), ('\u1da6', &['\u026a']),
+ ('\u1da7', &['\u1d7b']), ('\u1da8', &['\u029d']), ('\u1da9', &['\u026d']), ('\u1daa',
+ &['\u1d85']), ('\u1dab', &['\u029f']), ('\u1dac', &['\u0271']), ('\u1dad', &['\u0270']),
+ ('\u1dae', &['\u0272']), ('\u1daf', &['\u0273']), ('\u1db0', &['\u0274']), ('\u1db1',
+ &['\u0275']), ('\u1db2', &['\u0278']), ('\u1db3', &['\u0282']), ('\u1db4', &['\u0283']),
+ ('\u1db5', &['\u01ab']), ('\u1db6', &['\u0289']), ('\u1db7', &['\u028a']), ('\u1db8',
+ &['\u1d1c']), ('\u1db9', &['\u028b']), ('\u1dba', &['\u028c']), ('\u1dbb', &['\x7a']),
+ ('\u1dbc', &['\u0290']), ('\u1dbd', &['\u0291']), ('\u1dbe', &['\u0292']), ('\u1dbf',
+ &['\u03b8']), ('\u1e9a', &['\x61', '\u02be']), ('\u1fbd', &['\x20', '\u0313']), ('\u1fbf',
+ &['\x20', '\u0313']), ('\u1fc0', &['\x20', '\u0342']), ('\u1ffe', &['\x20', '\u0314']),
+ ('\u2002', &['\x20']), ('\u2003', &['\x20']), ('\u2004', &['\x20']), ('\u2005', &['\x20']),
+ ('\u2006', &['\x20']), ('\u2007', &['\x20']), ('\u2008', &['\x20']), ('\u2009', &['\x20']),
+ ('\u200a', &['\x20']), ('\u2011', &['\u2010']), ('\u2017', &['\x20', '\u0333']), ('\u2024',
+ &['\x2e']), ('\u2025', &['\x2e', '\x2e']), ('\u2026', &['\x2e', '\x2e', '\x2e']), ('\u202f',
+ &['\x20']), ('\u2033', &['\u2032', '\u2032']), ('\u2034', &['\u2032', '\u2032', '\u2032']),
+ ('\u2036', &['\u2035', '\u2035']), ('\u2037', &['\u2035', '\u2035', '\u2035']), ('\u203c',
+ &['\x21', '\x21']), ('\u203e', &['\x20', '\u0305']), ('\u2047', &['\x3f', '\x3f']),
+ ('\u2048', &['\x3f', '\x21']), ('\u2049', &['\x21', '\x3f']), ('\u2057', &['\u2032',
+ '\u2032', '\u2032', '\u2032']), ('\u205f', &['\x20']), ('\u2070', &['\x30']), ('\u2071',
+ &['\x69']), ('\u2074', &['\x34']), ('\u2075', &['\x35']), ('\u2076', &['\x36']), ('\u2077',
+ &['\x37']), ('\u2078', &['\x38']), ('\u2079', &['\x39']), ('\u207a', &['\x2b']), ('\u207b',
+ &['\u2212']), ('\u207c', &['\x3d']), ('\u207d', &['\x28']), ('\u207e', &['\x29']),
+ ('\u207f', &['\x6e']), ('\u2080', &['\x30']), ('\u2081', &['\x31']), ('\u2082', &['\x32']),
+ ('\u2083', &['\x33']), ('\u2084', &['\x34']), ('\u2085', &['\x35']), ('\u2086', &['\x36']),
+ ('\u2087', &['\x37']), ('\u2088', &['\x38']), ('\u2089', &['\x39']), ('\u208a', &['\x2b']),
+ ('\u208b', &['\u2212']), ('\u208c', &['\x3d']), ('\u208d', &['\x28']), ('\u208e',
+ &['\x29']), ('\u2090', &['\x61']), ('\u2091', &['\x65']), ('\u2092', &['\x6f']), ('\u2093',
+ &['\x78']), ('\u2094', &['\u0259']), ('\u2095', &['\x68']), ('\u2096', &['\x6b']),
+ ('\u2097', &['\x6c']), ('\u2098', &['\x6d']), ('\u2099', &['\x6e']), ('\u209a', &['\x70']),
+ ('\u209b', &['\x73']), ('\u209c', &['\x74']), ('\u20a8', &['\x52', '\x73']), ('\u2100',
+ &['\x61', '\x2f', '\x63']), ('\u2101', &['\x61', '\x2f', '\x73']), ('\u2102', &['\x43']),
+ ('\u2103', &['\xb0', '\x43']), ('\u2105', &['\x63', '\x2f', '\x6f']), ('\u2106', &['\x63',
+ '\x2f', '\x75']), ('\u2107', &['\u0190']), ('\u2109', &['\xb0', '\x46']), ('\u210a',
+ &['\x67']), ('\u210b', &['\x48']), ('\u210c', &['\x48']), ('\u210d', &['\x48']), ('\u210e',
+ &['\x68']), ('\u210f', &['\u0127']), ('\u2110', &['\x49']), ('\u2111', &['\x49']),
+ ('\u2112', &['\x4c']), ('\u2113', &['\x6c']), ('\u2115', &['\x4e']), ('\u2116', &['\x4e',
+ '\x6f']), ('\u2119', &['\x50']), ('\u211a', &['\x51']), ('\u211b', &['\x52']), ('\u211c',
+ &['\x52']), ('\u211d', &['\x52']), ('\u2120', &['\x53', '\x4d']), ('\u2121', &['\x54',
+ '\x45', '\x4c']), ('\u2122', &['\x54', '\x4d']), ('\u2124', &['\x5a']), ('\u2128',
+ &['\x5a']), ('\u212c', &['\x42']), ('\u212d', &['\x43']), ('\u212f', &['\x65']), ('\u2130',
+ &['\x45']), ('\u2131', &['\x46']), ('\u2133', &['\x4d']), ('\u2134', &['\x6f']), ('\u2135',
+ &['\u05d0']), ('\u2136', &['\u05d1']), ('\u2137', &['\u05d2']), ('\u2138', &['\u05d3']),
+ ('\u2139', &['\x69']), ('\u213b', &['\x46', '\x41', '\x58']), ('\u213c', &['\u03c0']),
+ ('\u213d', &['\u03b3']), ('\u213e', &['\u0393']), ('\u213f', &['\u03a0']), ('\u2140',
+ &['\u2211']), ('\u2145', &['\x44']), ('\u2146', &['\x64']), ('\u2147', &['\x65']),
+ ('\u2148', &['\x69']), ('\u2149', &['\x6a']), ('\u2150', &['\x31', '\u2044', '\x37']),
+ ('\u2151', &['\x31', '\u2044', '\x39']), ('\u2152', &['\x31', '\u2044', '\x31', '\x30']),
+ ('\u2153', &['\x31', '\u2044', '\x33']), ('\u2154', &['\x32', '\u2044', '\x33']), ('\u2155',
+ &['\x31', '\u2044', '\x35']), ('\u2156', &['\x32', '\u2044', '\x35']), ('\u2157', &['\x33',
+ '\u2044', '\x35']), ('\u2158', &['\x34', '\u2044', '\x35']), ('\u2159', &['\x31', '\u2044',
+ '\x36']), ('\u215a', &['\x35', '\u2044', '\x36']), ('\u215b', &['\x31', '\u2044', '\x38']),
+ ('\u215c', &['\x33', '\u2044', '\x38']), ('\u215d', &['\x35', '\u2044', '\x38']), ('\u215e',
+ &['\x37', '\u2044', '\x38']), ('\u215f', &['\x31', '\u2044']), ('\u2160', &['\x49']),
+ ('\u2161', &['\x49', '\x49']), ('\u2162', &['\x49', '\x49', '\x49']), ('\u2163', &['\x49',
+ '\x56']), ('\u2164', &['\x56']), ('\u2165', &['\x56', '\x49']), ('\u2166', &['\x56', '\x49',
+ '\x49']), ('\u2167', &['\x56', '\x49', '\x49', '\x49']), ('\u2168', &['\x49', '\x58']),
+ ('\u2169', &['\x58']), ('\u216a', &['\x58', '\x49']), ('\u216b', &['\x58', '\x49', '\x49']),
+ ('\u216c', &['\x4c']), ('\u216d', &['\x43']), ('\u216e', &['\x44']), ('\u216f', &['\x4d']),
+ ('\u2170', &['\x69']), ('\u2171', &['\x69', '\x69']), ('\u2172', &['\x69', '\x69', '\x69']),
+ ('\u2173', &['\x69', '\x76']), ('\u2174', &['\x76']), ('\u2175', &['\x76', '\x69']),
+ ('\u2176', &['\x76', '\x69', '\x69']), ('\u2177', &['\x76', '\x69', '\x69', '\x69']),
+ ('\u2178', &['\x69', '\x78']), ('\u2179', &['\x78']), ('\u217a', &['\x78', '\x69']),
+ ('\u217b', &['\x78', '\x69', '\x69']), ('\u217c', &['\x6c']), ('\u217d', &['\x63']),
+ ('\u217e', &['\x64']), ('\u217f', &['\x6d']), ('\u2189', &['\x30', '\u2044', '\x33']),
+ ('\u222c', &['\u222b', '\u222b']), ('\u222d', &['\u222b', '\u222b', '\u222b']), ('\u222f',
+ &['\u222e', '\u222e']), ('\u2230', &['\u222e', '\u222e', '\u222e']), ('\u2460', &['\x31']),
+ ('\u2461', &['\x32']), ('\u2462', &['\x33']), ('\u2463', &['\x34']), ('\u2464', &['\x35']),
+ ('\u2465', &['\x36']), ('\u2466', &['\x37']), ('\u2467', &['\x38']), ('\u2468', &['\x39']),
+ ('\u2469', &['\x31', '\x30']), ('\u246a', &['\x31', '\x31']), ('\u246b', &['\x31', '\x32']),
+ ('\u246c', &['\x31', '\x33']), ('\u246d', &['\x31', '\x34']), ('\u246e', &['\x31', '\x35']),
+ ('\u246f', &['\x31', '\x36']), ('\u2470', &['\x31', '\x37']), ('\u2471', &['\x31', '\x38']),
+ ('\u2472', &['\x31', '\x39']), ('\u2473', &['\x32', '\x30']), ('\u2474', &['\x28', '\x31',
+ '\x29']), ('\u2475', &['\x28', '\x32', '\x29']), ('\u2476', &['\x28', '\x33', '\x29']),
+ ('\u2477', &['\x28', '\x34', '\x29']), ('\u2478', &['\x28', '\x35', '\x29']), ('\u2479',
+ &['\x28', '\x36', '\x29']), ('\u247a', &['\x28', '\x37', '\x29']), ('\u247b', &['\x28',
+ '\x38', '\x29']), ('\u247c', &['\x28', '\x39', '\x29']), ('\u247d', &['\x28', '\x31',
+ '\x30', '\x29']), ('\u247e', &['\x28', '\x31', '\x31', '\x29']), ('\u247f', &['\x28',
+ '\x31', '\x32', '\x29']), ('\u2480', &['\x28', '\x31', '\x33', '\x29']), ('\u2481',
+ &['\x28', '\x31', '\x34', '\x29']), ('\u2482', &['\x28', '\x31', '\x35', '\x29']),
+ ('\u2483', &['\x28', '\x31', '\x36', '\x29']), ('\u2484', &['\x28', '\x31', '\x37',
+ '\x29']), ('\u2485', &['\x28', '\x31', '\x38', '\x29']), ('\u2486', &['\x28', '\x31',
+ '\x39', '\x29']), ('\u2487', &['\x28', '\x32', '\x30', '\x29']), ('\u2488', &['\x31',
+ '\x2e']), ('\u2489', &['\x32', '\x2e']), ('\u248a', &['\x33', '\x2e']), ('\u248b', &['\x34',
+ '\x2e']), ('\u248c', &['\x35', '\x2e']), ('\u248d', &['\x36', '\x2e']), ('\u248e', &['\x37',
+ '\x2e']), ('\u248f', &['\x38', '\x2e']), ('\u2490', &['\x39', '\x2e']), ('\u2491', &['\x31',
+ '\x30', '\x2e']), ('\u2492', &['\x31', '\x31', '\x2e']), ('\u2493', &['\x31', '\x32',
+ '\x2e']), ('\u2494', &['\x31', '\x33', '\x2e']), ('\u2495', &['\x31', '\x34', '\x2e']),
+ ('\u2496', &['\x31', '\x35', '\x2e']), ('\u2497', &['\x31', '\x36', '\x2e']), ('\u2498',
+ &['\x31', '\x37', '\x2e']), ('\u2499', &['\x31', '\x38', '\x2e']), ('\u249a', &['\x31',
+ '\x39', '\x2e']), ('\u249b', &['\x32', '\x30', '\x2e']), ('\u249c', &['\x28', '\x61',
+ '\x29']), ('\u249d', &['\x28', '\x62', '\x29']), ('\u249e', &['\x28', '\x63', '\x29']),
+ ('\u249f', &['\x28', '\x64', '\x29']), ('\u24a0', &['\x28', '\x65', '\x29']), ('\u24a1',
+ &['\x28', '\x66', '\x29']), ('\u24a2', &['\x28', '\x67', '\x29']), ('\u24a3', &['\x28',
+ '\x68', '\x29']), ('\u24a4', &['\x28', '\x69', '\x29']), ('\u24a5', &['\x28', '\x6a',
+ '\x29']), ('\u24a6', &['\x28', '\x6b', '\x29']), ('\u24a7', &['\x28', '\x6c', '\x29']),
+ ('\u24a8', &['\x28', '\x6d', '\x29']), ('\u24a9', &['\x28', '\x6e', '\x29']), ('\u24aa',
+ &['\x28', '\x6f', '\x29']), ('\u24ab', &['\x28', '\x70', '\x29']), ('\u24ac', &['\x28',
+ '\x71', '\x29']), ('\u24ad', &['\x28', '\x72', '\x29']), ('\u24ae', &['\x28', '\x73',
+ '\x29']), ('\u24af', &['\x28', '\x74', '\x29']), ('\u24b0', &['\x28', '\x75', '\x29']),
+ ('\u24b1', &['\x28', '\x76', '\x29']), ('\u24b2', &['\x28', '\x77', '\x29']), ('\u24b3',
+ &['\x28', '\x78', '\x29']), ('\u24b4', &['\x28', '\x79', '\x29']), ('\u24b5', &['\x28',
+ '\x7a', '\x29']), ('\u24b6', &['\x41']), ('\u24b7', &['\x42']), ('\u24b8', &['\x43']),
+ ('\u24b9', &['\x44']), ('\u24ba', &['\x45']), ('\u24bb', &['\x46']), ('\u24bc', &['\x47']),
+ ('\u24bd', &['\x48']), ('\u24be', &['\x49']), ('\u24bf', &['\x4a']), ('\u24c0', &['\x4b']),
+ ('\u24c1', &['\x4c']), ('\u24c2', &['\x4d']), ('\u24c3', &['\x4e']), ('\u24c4', &['\x4f']),
+ ('\u24c5', &['\x50']), ('\u24c6', &['\x51']), ('\u24c7', &['\x52']), ('\u24c8', &['\x53']),
+ ('\u24c9', &['\x54']), ('\u24ca', &['\x55']), ('\u24cb', &['\x56']), ('\u24cc', &['\x57']),
+ ('\u24cd', &['\x58']), ('\u24ce', &['\x59']), ('\u24cf', &['\x5a']), ('\u24d0', &['\x61']),
+ ('\u24d1', &['\x62']), ('\u24d2', &['\x63']), ('\u24d3', &['\x64']), ('\u24d4', &['\x65']),
+ ('\u24d5', &['\x66']), ('\u24d6', &['\x67']), ('\u24d7', &['\x68']), ('\u24d8', &['\x69']),
+ ('\u24d9', &['\x6a']), ('\u24da', &['\x6b']), ('\u24db', &['\x6c']), ('\u24dc', &['\x6d']),
+ ('\u24dd', &['\x6e']), ('\u24de', &['\x6f']), ('\u24df', &['\x70']), ('\u24e0', &['\x71']),
+ ('\u24e1', &['\x72']), ('\u24e2', &['\x73']), ('\u24e3', &['\x74']), ('\u24e4', &['\x75']),
+ ('\u24e5', &['\x76']), ('\u24e6', &['\x77']), ('\u24e7', &['\x78']), ('\u24e8', &['\x79']),
+ ('\u24e9', &['\x7a']), ('\u24ea', &['\x30']), ('\u2a0c', &['\u222b', '\u222b', '\u222b',
+ '\u222b']), ('\u2a74', &['\x3a', '\x3a', '\x3d']), ('\u2a75', &['\x3d', '\x3d']), ('\u2a76',
+ &['\x3d', '\x3d', '\x3d']), ('\u2c7c', &['\x6a']), ('\u2c7d', &['\x56']), ('\u2d6f',
+ &['\u2d61']), ('\u2e9f', &['\u6bcd']), ('\u2ef3', &['\u9f9f']), ('\u2f00', &['\u4e00']),
+ ('\u2f01', &['\u4e28']), ('\u2f02', &['\u4e36']), ('\u2f03', &['\u4e3f']), ('\u2f04',
+ &['\u4e59']), ('\u2f05', &['\u4e85']), ('\u2f06', &['\u4e8c']), ('\u2f07', &['\u4ea0']),
+ ('\u2f08', &['\u4eba']), ('\u2f09', &['\u513f']), ('\u2f0a', &['\u5165']), ('\u2f0b',
+ &['\u516b']), ('\u2f0c', &['\u5182']), ('\u2f0d', &['\u5196']), ('\u2f0e', &['\u51ab']),
+ ('\u2f0f', &['\u51e0']), ('\u2f10', &['\u51f5']), ('\u2f11', &['\u5200']), ('\u2f12',
+ &['\u529b']), ('\u2f13', &['\u52f9']), ('\u2f14', &['\u5315']), ('\u2f15', &['\u531a']),
+ ('\u2f16', &['\u5338']), ('\u2f17', &['\u5341']), ('\u2f18', &['\u535c']), ('\u2f19',
+ &['\u5369']), ('\u2f1a', &['\u5382']), ('\u2f1b', &['\u53b6']), ('\u2f1c', &['\u53c8']),
+ ('\u2f1d', &['\u53e3']), ('\u2f1e', &['\u56d7']), ('\u2f1f', &['\u571f']), ('\u2f20',
+ &['\u58eb']), ('\u2f21', &['\u5902']), ('\u2f22', &['\u590a']), ('\u2f23', &['\u5915']),
+ ('\u2f24', &['\u5927']), ('\u2f25', &['\u5973']), ('\u2f26', &['\u5b50']), ('\u2f27',
+ &['\u5b80']), ('\u2f28', &['\u5bf8']), ('\u2f29', &['\u5c0f']), ('\u2f2a', &['\u5c22']),
+ ('\u2f2b', &['\u5c38']), ('\u2f2c', &['\u5c6e']), ('\u2f2d', &['\u5c71']), ('\u2f2e',
+ &['\u5ddb']), ('\u2f2f', &['\u5de5']), ('\u2f30', &['\u5df1']), ('\u2f31', &['\u5dfe']),
+ ('\u2f32', &['\u5e72']), ('\u2f33', &['\u5e7a']), ('\u2f34', &['\u5e7f']), ('\u2f35',
+ &['\u5ef4']), ('\u2f36', &['\u5efe']), ('\u2f37', &['\u5f0b']), ('\u2f38', &['\u5f13']),
+ ('\u2f39', &['\u5f50']), ('\u2f3a', &['\u5f61']), ('\u2f3b', &['\u5f73']), ('\u2f3c',
+ &['\u5fc3']), ('\u2f3d', &['\u6208']), ('\u2f3e', &['\u6236']), ('\u2f3f', &['\u624b']),
+ ('\u2f40', &['\u652f']), ('\u2f41', &['\u6534']), ('\u2f42', &['\u6587']), ('\u2f43',
+ &['\u6597']), ('\u2f44', &['\u65a4']), ('\u2f45', &['\u65b9']), ('\u2f46', &['\u65e0']),
+ ('\u2f47', &['\u65e5']), ('\u2f48', &['\u66f0']), ('\u2f49', &['\u6708']), ('\u2f4a',
+ &['\u6728']), ('\u2f4b', &['\u6b20']), ('\u2f4c', &['\u6b62']), ('\u2f4d', &['\u6b79']),
+ ('\u2f4e', &['\u6bb3']), ('\u2f4f', &['\u6bcb']), ('\u2f50', &['\u6bd4']), ('\u2f51',
+ &['\u6bdb']), ('\u2f52', &['\u6c0f']), ('\u2f53', &['\u6c14']), ('\u2f54', &['\u6c34']),
+ ('\u2f55', &['\u706b']), ('\u2f56', &['\u722a']), ('\u2f57', &['\u7236']), ('\u2f58',
+ &['\u723b']), ('\u2f59', &['\u723f']), ('\u2f5a', &['\u7247']), ('\u2f5b', &['\u7259']),
+ ('\u2f5c', &['\u725b']), ('\u2f5d', &['\u72ac']), ('\u2f5e', &['\u7384']), ('\u2f5f',
+ &['\u7389']), ('\u2f60', &['\u74dc']), ('\u2f61', &['\u74e6']), ('\u2f62', &['\u7518']),
+ ('\u2f63', &['\u751f']), ('\u2f64', &['\u7528']), ('\u2f65', &['\u7530']), ('\u2f66',
+ &['\u758b']), ('\u2f67', &['\u7592']), ('\u2f68', &['\u7676']), ('\u2f69', &['\u767d']),
+ ('\u2f6a', &['\u76ae']), ('\u2f6b', &['\u76bf']), ('\u2f6c', &['\u76ee']), ('\u2f6d',
+ &['\u77db']), ('\u2f6e', &['\u77e2']), ('\u2f6f', &['\u77f3']), ('\u2f70', &['\u793a']),
+ ('\u2f71', &['\u79b8']), ('\u2f72', &['\u79be']), ('\u2f73', &['\u7a74']), ('\u2f74',
+ &['\u7acb']), ('\u2f75', &['\u7af9']), ('\u2f76', &['\u7c73']), ('\u2f77', &['\u7cf8']),
+ ('\u2f78', &['\u7f36']), ('\u2f79', &['\u7f51']), ('\u2f7a', &['\u7f8a']), ('\u2f7b',
+ &['\u7fbd']), ('\u2f7c', &['\u8001']), ('\u2f7d', &['\u800c']), ('\u2f7e', &['\u8012']),
+ ('\u2f7f', &['\u8033']), ('\u2f80', &['\u807f']), ('\u2f81', &['\u8089']), ('\u2f82',
+ &['\u81e3']), ('\u2f83', &['\u81ea']), ('\u2f84', &['\u81f3']), ('\u2f85', &['\u81fc']),
+ ('\u2f86', &['\u820c']), ('\u2f87', &['\u821b']), ('\u2f88', &['\u821f']), ('\u2f89',
+ &['\u826e']), ('\u2f8a', &['\u8272']), ('\u2f8b', &['\u8278']), ('\u2f8c', &['\u864d']),
+ ('\u2f8d', &['\u866b']), ('\u2f8e', &['\u8840']), ('\u2f8f', &['\u884c']), ('\u2f90',
+ &['\u8863']), ('\u2f91', &['\u897e']), ('\u2f92', &['\u898b']), ('\u2f93', &['\u89d2']),
+ ('\u2f94', &['\u8a00']), ('\u2f95', &['\u8c37']), ('\u2f96', &['\u8c46']), ('\u2f97',
+ &['\u8c55']), ('\u2f98', &['\u8c78']), ('\u2f99', &['\u8c9d']), ('\u2f9a', &['\u8d64']),
+ ('\u2f9b', &['\u8d70']), ('\u2f9c', &['\u8db3']), ('\u2f9d', &['\u8eab']), ('\u2f9e',
+ &['\u8eca']), ('\u2f9f', &['\u8f9b']), ('\u2fa0', &['\u8fb0']), ('\u2fa1', &['\u8fb5']),
+ ('\u2fa2', &['\u9091']), ('\u2fa3', &['\u9149']), ('\u2fa4', &['\u91c6']), ('\u2fa5',
+ &['\u91cc']), ('\u2fa6', &['\u91d1']), ('\u2fa7', &['\u9577']), ('\u2fa8', &['\u9580']),
+ ('\u2fa9', &['\u961c']), ('\u2faa', &['\u96b6']), ('\u2fab', &['\u96b9']), ('\u2fac',
+ &['\u96e8']), ('\u2fad', &['\u9751']), ('\u2fae', &['\u975e']), ('\u2faf', &['\u9762']),
+ ('\u2fb0', &['\u9769']), ('\u2fb1', &['\u97cb']), ('\u2fb2', &['\u97ed']), ('\u2fb3',
+ &['\u97f3']), ('\u2fb4', &['\u9801']), ('\u2fb5', &['\u98a8']), ('\u2fb6', &['\u98db']),
+ ('\u2fb7', &['\u98df']), ('\u2fb8', &['\u9996']), ('\u2fb9', &['\u9999']), ('\u2fba',
+ &['\u99ac']), ('\u2fbb', &['\u9aa8']), ('\u2fbc', &['\u9ad8']), ('\u2fbd', &['\u9adf']),
+ ('\u2fbe', &['\u9b25']), ('\u2fbf', &['\u9b2f']), ('\u2fc0', &['\u9b32']), ('\u2fc1',
+ &['\u9b3c']), ('\u2fc2', &['\u9b5a']), ('\u2fc3', &['\u9ce5']), ('\u2fc4', &['\u9e75']),
+ ('\u2fc5', &['\u9e7f']), ('\u2fc6', &['\u9ea5']), ('\u2fc7', &['\u9ebb']), ('\u2fc8',
+ &['\u9ec3']), ('\u2fc9', &['\u9ecd']), ('\u2fca', &['\u9ed1']), ('\u2fcb', &['\u9ef9']),
+ ('\u2fcc', &['\u9efd']), ('\u2fcd', &['\u9f0e']), ('\u2fce', &['\u9f13']), ('\u2fcf',
+ &['\u9f20']), ('\u2fd0', &['\u9f3b']), ('\u2fd1', &['\u9f4a']), ('\u2fd2', &['\u9f52']),
+ ('\u2fd3', &['\u9f8d']), ('\u2fd4', &['\u9f9c']), ('\u2fd5', &['\u9fa0']), ('\u3000',
+ &['\x20']), ('\u3036', &['\u3012']), ('\u3038', &['\u5341']), ('\u3039', &['\u5344']),
+ ('\u303a', &['\u5345']), ('\u309b', &['\x20', '\u3099']), ('\u309c', &['\x20', '\u309a']),
+ ('\u309f', &['\u3088', '\u308a']), ('\u30ff', &['\u30b3', '\u30c8']), ('\u3131',
+ &['\u1100']), ('\u3132', &['\u1101']), ('\u3133', &['\u11aa']), ('\u3134', &['\u1102']),
+ ('\u3135', &['\u11ac']), ('\u3136', &['\u11ad']), ('\u3137', &['\u1103']), ('\u3138',
+ &['\u1104']), ('\u3139', &['\u1105']), ('\u313a', &['\u11b0']), ('\u313b', &['\u11b1']),
+ ('\u313c', &['\u11b2']), ('\u313d', &['\u11b3']), ('\u313e', &['\u11b4']), ('\u313f',
+ &['\u11b5']), ('\u3140', &['\u111a']), ('\u3141', &['\u1106']), ('\u3142', &['\u1107']),
+ ('\u3143', &['\u1108']), ('\u3144', &['\u1121']), ('\u3145', &['\u1109']), ('\u3146',
+ &['\u110a']), ('\u3147', &['\u110b']), ('\u3148', &['\u110c']), ('\u3149', &['\u110d']),
+ ('\u314a', &['\u110e']), ('\u314b', &['\u110f']), ('\u314c', &['\u1110']), ('\u314d',
+ &['\u1111']), ('\u314e', &['\u1112']), ('\u314f', &['\u1161']), ('\u3150', &['\u1162']),
+ ('\u3151', &['\u1163']), ('\u3152', &['\u1164']), ('\u3153', &['\u1165']), ('\u3154',
+ &['\u1166']), ('\u3155', &['\u1167']), ('\u3156', &['\u1168']), ('\u3157', &['\u1169']),
+ ('\u3158', &['\u116a']), ('\u3159', &['\u116b']), ('\u315a', &['\u116c']), ('\u315b',
+ &['\u116d']), ('\u315c', &['\u116e']), ('\u315d', &['\u116f']), ('\u315e', &['\u1170']),
+ ('\u315f', &['\u1171']), ('\u3160', &['\u1172']), ('\u3161', &['\u1173']), ('\u3162',
+ &['\u1174']), ('\u3163', &['\u1175']), ('\u3164', &['\u1160']), ('\u3165', &['\u1114']),
+ ('\u3166', &['\u1115']), ('\u3167', &['\u11c7']), ('\u3168', &['\u11c8']), ('\u3169',
+ &['\u11cc']), ('\u316a', &['\u11ce']), ('\u316b', &['\u11d3']), ('\u316c', &['\u11d7']),
+ ('\u316d', &['\u11d9']), ('\u316e', &['\u111c']), ('\u316f', &['\u11dd']), ('\u3170',
+ &['\u11df']), ('\u3171', &['\u111d']), ('\u3172', &['\u111e']), ('\u3173', &['\u1120']),
+ ('\u3174', &['\u1122']), ('\u3175', &['\u1123']), ('\u3176', &['\u1127']), ('\u3177',
+ &['\u1129']), ('\u3178', &['\u112b']), ('\u3179', &['\u112c']), ('\u317a', &['\u112d']),
+ ('\u317b', &['\u112e']), ('\u317c', &['\u112f']), ('\u317d', &['\u1132']), ('\u317e',
+ &['\u1136']), ('\u317f', &['\u1140']), ('\u3180', &['\u1147']), ('\u3181', &['\u114c']),
+ ('\u3182', &['\u11f1']), ('\u3183', &['\u11f2']), ('\u3184', &['\u1157']), ('\u3185',
+ &['\u1158']), ('\u3186', &['\u1159']), ('\u3187', &['\u1184']), ('\u3188', &['\u1185']),
+ ('\u3189', &['\u1188']), ('\u318a', &['\u1191']), ('\u318b', &['\u1192']), ('\u318c',
+ &['\u1194']), ('\u318d', &['\u119e']), ('\u318e', &['\u11a1']), ('\u3192', &['\u4e00']),
+ ('\u3193', &['\u4e8c']), ('\u3194', &['\u4e09']), ('\u3195', &['\u56db']), ('\u3196',
+ &['\u4e0a']), ('\u3197', &['\u4e2d']), ('\u3198', &['\u4e0b']), ('\u3199', &['\u7532']),
+ ('\u319a', &['\u4e59']), ('\u319b', &['\u4e19']), ('\u319c', &['\u4e01']), ('\u319d',
+ &['\u5929']), ('\u319e', &['\u5730']), ('\u319f', &['\u4eba']), ('\u3200', &['\x28',
+ '\u1100', '\x29']), ('\u3201', &['\x28', '\u1102', '\x29']), ('\u3202', &['\x28', '\u1103',
+ '\x29']), ('\u3203', &['\x28', '\u1105', '\x29']), ('\u3204', &['\x28', '\u1106', '\x29']),
+ ('\u3205', &['\x28', '\u1107', '\x29']), ('\u3206', &['\x28', '\u1109', '\x29']), ('\u3207',
+ &['\x28', '\u110b', '\x29']), ('\u3208', &['\x28', '\u110c', '\x29']), ('\u3209', &['\x28',
+ '\u110e', '\x29']), ('\u320a', &['\x28', '\u110f', '\x29']), ('\u320b', &['\x28', '\u1110',
+ '\x29']), ('\u320c', &['\x28', '\u1111', '\x29']), ('\u320d', &['\x28', '\u1112', '\x29']),
+ ('\u320e', &['\x28', '\u1100', '\u1161', '\x29']), ('\u320f', &['\x28', '\u1102', '\u1161',
+ '\x29']), ('\u3210', &['\x28', '\u1103', '\u1161', '\x29']), ('\u3211', &['\x28', '\u1105',
+ '\u1161', '\x29']), ('\u3212', &['\x28', '\u1106', '\u1161', '\x29']), ('\u3213', &['\x28',
+ '\u1107', '\u1161', '\x29']), ('\u3214', &['\x28', '\u1109', '\u1161', '\x29']), ('\u3215',
+ &['\x28', '\u110b', '\u1161', '\x29']), ('\u3216', &['\x28', '\u110c', '\u1161', '\x29']),
+ ('\u3217', &['\x28', '\u110e', '\u1161', '\x29']), ('\u3218', &['\x28', '\u110f', '\u1161',
+ '\x29']), ('\u3219', &['\x28', '\u1110', '\u1161', '\x29']), ('\u321a', &['\x28', '\u1111',
+ '\u1161', '\x29']), ('\u321b', &['\x28', '\u1112', '\u1161', '\x29']), ('\u321c', &['\x28',
+ '\u110c', '\u116e', '\x29']), ('\u321d', &['\x28', '\u110b', '\u1169', '\u110c', '\u1165',
+ '\u11ab', '\x29']), ('\u321e', &['\x28', '\u110b', '\u1169', '\u1112', '\u116e', '\x29']),
+ ('\u3220', &['\x28', '\u4e00', '\x29']), ('\u3221', &['\x28', '\u4e8c', '\x29']), ('\u3222',
+ &['\x28', '\u4e09', '\x29']), ('\u3223', &['\x28', '\u56db', '\x29']), ('\u3224', &['\x28',
+ '\u4e94', '\x29']), ('\u3225', &['\x28', '\u516d', '\x29']), ('\u3226', &['\x28', '\u4e03',
+ '\x29']), ('\u3227', &['\x28', '\u516b', '\x29']), ('\u3228', &['\x28', '\u4e5d', '\x29']),
+ ('\u3229', &['\x28', '\u5341', '\x29']), ('\u322a', &['\x28', '\u6708', '\x29']), ('\u322b',
+ &['\x28', '\u706b', '\x29']), ('\u322c', &['\x28', '\u6c34', '\x29']), ('\u322d', &['\x28',
+ '\u6728', '\x29']), ('\u322e', &['\x28', '\u91d1', '\x29']), ('\u322f', &['\x28', '\u571f',
+ '\x29']), ('\u3230', &['\x28', '\u65e5', '\x29']), ('\u3231', &['\x28', '\u682a', '\x29']),
+ ('\u3232', &['\x28', '\u6709', '\x29']), ('\u3233', &['\x28', '\u793e', '\x29']), ('\u3234',
+ &['\x28', '\u540d', '\x29']), ('\u3235', &['\x28', '\u7279', '\x29']), ('\u3236', &['\x28',
+ '\u8ca1', '\x29']), ('\u3237', &['\x28', '\u795d', '\x29']), ('\u3238', &['\x28', '\u52b4',
+ '\x29']), ('\u3239', &['\x28', '\u4ee3', '\x29']), ('\u323a', &['\x28', '\u547c', '\x29']),
+ ('\u323b', &['\x28', '\u5b66', '\x29']), ('\u323c', &['\x28', '\u76e3', '\x29']), ('\u323d',
+ &['\x28', '\u4f01', '\x29']), ('\u323e', &['\x28', '\u8cc7', '\x29']), ('\u323f', &['\x28',
+ '\u5354', '\x29']), ('\u3240', &['\x28', '\u796d', '\x29']), ('\u3241', &['\x28', '\u4f11',
+ '\x29']), ('\u3242', &['\x28', '\u81ea', '\x29']), ('\u3243', &['\x28', '\u81f3', '\x29']),
+ ('\u3244', &['\u554f']), ('\u3245', &['\u5e7c']), ('\u3246', &['\u6587']), ('\u3247',
+ &['\u7b8f']), ('\u3250', &['\x50', '\x54', '\x45']), ('\u3251', &['\x32', '\x31']),
+ ('\u3252', &['\x32', '\x32']), ('\u3253', &['\x32', '\x33']), ('\u3254', &['\x32', '\x34']),
+ ('\u3255', &['\x32', '\x35']), ('\u3256', &['\x32', '\x36']), ('\u3257', &['\x32', '\x37']),
+ ('\u3258', &['\x32', '\x38']), ('\u3259', &['\x32', '\x39']), ('\u325a', &['\x33', '\x30']),
+ ('\u325b', &['\x33', '\x31']), ('\u325c', &['\x33', '\x32']), ('\u325d', &['\x33', '\x33']),
+ ('\u325e', &['\x33', '\x34']), ('\u325f', &['\x33', '\x35']), ('\u3260', &['\u1100']),
+ ('\u3261', &['\u1102']), ('\u3262', &['\u1103']), ('\u3263', &['\u1105']), ('\u3264',
+ &['\u1106']), ('\u3265', &['\u1107']), ('\u3266', &['\u1109']), ('\u3267', &['\u110b']),
+ ('\u3268', &['\u110c']), ('\u3269', &['\u110e']), ('\u326a', &['\u110f']), ('\u326b',
+ &['\u1110']), ('\u326c', &['\u1111']), ('\u326d', &['\u1112']), ('\u326e', &['\u1100',
+ '\u1161']), ('\u326f', &['\u1102', '\u1161']), ('\u3270', &['\u1103', '\u1161']), ('\u3271',
+ &['\u1105', '\u1161']), ('\u3272', &['\u1106', '\u1161']), ('\u3273', &['\u1107',
+ '\u1161']), ('\u3274', &['\u1109', '\u1161']), ('\u3275', &['\u110b', '\u1161']), ('\u3276',
+ &['\u110c', '\u1161']), ('\u3277', &['\u110e', '\u1161']), ('\u3278', &['\u110f',
+ '\u1161']), ('\u3279', &['\u1110', '\u1161']), ('\u327a', &['\u1111', '\u1161']), ('\u327b',
+ &['\u1112', '\u1161']), ('\u327c', &['\u110e', '\u1161', '\u11b7', '\u1100', '\u1169']),
+ ('\u327d', &['\u110c', '\u116e', '\u110b', '\u1174']), ('\u327e', &['\u110b', '\u116e']),
+ ('\u3280', &['\u4e00']), ('\u3281', &['\u4e8c']), ('\u3282', &['\u4e09']), ('\u3283',
+ &['\u56db']), ('\u3284', &['\u4e94']), ('\u3285', &['\u516d']), ('\u3286', &['\u4e03']),
+ ('\u3287', &['\u516b']), ('\u3288', &['\u4e5d']), ('\u3289', &['\u5341']), ('\u328a',
+ &['\u6708']), ('\u328b', &['\u706b']), ('\u328c', &['\u6c34']), ('\u328d', &['\u6728']),
+ ('\u328e', &['\u91d1']), ('\u328f', &['\u571f']), ('\u3290', &['\u65e5']), ('\u3291',
+ &['\u682a']), ('\u3292', &['\u6709']), ('\u3293', &['\u793e']), ('\u3294', &['\u540d']),
+ ('\u3295', &['\u7279']), ('\u3296', &['\u8ca1']), ('\u3297', &['\u795d']), ('\u3298',
+ &['\u52b4']), ('\u3299', &['\u79d8']), ('\u329a', &['\u7537']), ('\u329b', &['\u5973']),
+ ('\u329c', &['\u9069']), ('\u329d', &['\u512a']), ('\u329e', &['\u5370']), ('\u329f',
+ &['\u6ce8']), ('\u32a0', &['\u9805']), ('\u32a1', &['\u4f11']), ('\u32a2', &['\u5199']),
+ ('\u32a3', &['\u6b63']), ('\u32a4', &['\u4e0a']), ('\u32a5', &['\u4e2d']), ('\u32a6',
+ &['\u4e0b']), ('\u32a7', &['\u5de6']), ('\u32a8', &['\u53f3']), ('\u32a9', &['\u533b']),
+ ('\u32aa', &['\u5b97']), ('\u32ab', &['\u5b66']), ('\u32ac', &['\u76e3']), ('\u32ad',
+ &['\u4f01']), ('\u32ae', &['\u8cc7']), ('\u32af', &['\u5354']), ('\u32b0', &['\u591c']),
+ ('\u32b1', &['\x33', '\x36']), ('\u32b2', &['\x33', '\x37']), ('\u32b3', &['\x33', '\x38']),
+ ('\u32b4', &['\x33', '\x39']), ('\u32b5', &['\x34', '\x30']), ('\u32b6', &['\x34', '\x31']),
+ ('\u32b7', &['\x34', '\x32']), ('\u32b8', &['\x34', '\x33']), ('\u32b9', &['\x34', '\x34']),
+ ('\u32ba', &['\x34', '\x35']), ('\u32bb', &['\x34', '\x36']), ('\u32bc', &['\x34', '\x37']),
+ ('\u32bd', &['\x34', '\x38']), ('\u32be', &['\x34', '\x39']), ('\u32bf', &['\x35', '\x30']),
+ ('\u32c0', &['\x31', '\u6708']), ('\u32c1', &['\x32', '\u6708']), ('\u32c2', &['\x33',
+ '\u6708']), ('\u32c3', &['\x34', '\u6708']), ('\u32c4', &['\x35', '\u6708']), ('\u32c5',
+ &['\x36', '\u6708']), ('\u32c6', &['\x37', '\u6708']), ('\u32c7', &['\x38', '\u6708']),
+ ('\u32c8', &['\x39', '\u6708']), ('\u32c9', &['\x31', '\x30', '\u6708']), ('\u32ca',
+ &['\x31', '\x31', '\u6708']), ('\u32cb', &['\x31', '\x32', '\u6708']), ('\u32cc', &['\x48',
+ '\x67']), ('\u32cd', &['\x65', '\x72', '\x67']), ('\u32ce', &['\x65', '\x56']), ('\u32cf',
+ &['\x4c', '\x54', '\x44']), ('\u32d0', &['\u30a2']), ('\u32d1', &['\u30a4']), ('\u32d2',
+ &['\u30a6']), ('\u32d3', &['\u30a8']), ('\u32d4', &['\u30aa']), ('\u32d5', &['\u30ab']),
+ ('\u32d6', &['\u30ad']), ('\u32d7', &['\u30af']), ('\u32d8', &['\u30b1']), ('\u32d9',
+ &['\u30b3']), ('\u32da', &['\u30b5']), ('\u32db', &['\u30b7']), ('\u32dc', &['\u30b9']),
+ ('\u32dd', &['\u30bb']), ('\u32de', &['\u30bd']), ('\u32df', &['\u30bf']), ('\u32e0',
+ &['\u30c1']), ('\u32e1', &['\u30c4']), ('\u32e2', &['\u30c6']), ('\u32e3', &['\u30c8']),
+ ('\u32e4', &['\u30ca']), ('\u32e5', &['\u30cb']), ('\u32e6', &['\u30cc']), ('\u32e7',
+ &['\u30cd']), ('\u32e8', &['\u30ce']), ('\u32e9', &['\u30cf']), ('\u32ea', &['\u30d2']),
+ ('\u32eb', &['\u30d5']), ('\u32ec', &['\u30d8']), ('\u32ed', &['\u30db']), ('\u32ee',
+ &['\u30de']), ('\u32ef', &['\u30df']), ('\u32f0', &['\u30e0']), ('\u32f1', &['\u30e1']),
+ ('\u32f2', &['\u30e2']), ('\u32f3', &['\u30e4']), ('\u32f4', &['\u30e6']), ('\u32f5',
+ &['\u30e8']), ('\u32f6', &['\u30e9']), ('\u32f7', &['\u30ea']), ('\u32f8', &['\u30eb']),
+ ('\u32f9', &['\u30ec']), ('\u32fa', &['\u30ed']), ('\u32fb', &['\u30ef']), ('\u32fc',
+ &['\u30f0']), ('\u32fd', &['\u30f1']), ('\u32fe', &['\u30f2']), ('\u3300', &['\u30a2',
+ '\u30d1', '\u30fc', '\u30c8']), ('\u3301', &['\u30a2', '\u30eb', '\u30d5', '\u30a1']),
+ ('\u3302', &['\u30a2', '\u30f3', '\u30da', '\u30a2']), ('\u3303', &['\u30a2', '\u30fc',
+ '\u30eb']), ('\u3304', &['\u30a4', '\u30cb', '\u30f3', '\u30b0']), ('\u3305', &['\u30a4',
+ '\u30f3', '\u30c1']), ('\u3306', &['\u30a6', '\u30a9', '\u30f3']), ('\u3307', &['\u30a8',
+ '\u30b9', '\u30af', '\u30fc', '\u30c9']), ('\u3308', &['\u30a8', '\u30fc', '\u30ab',
+ '\u30fc']), ('\u3309', &['\u30aa', '\u30f3', '\u30b9']), ('\u330a', &['\u30aa', '\u30fc',
+ '\u30e0']), ('\u330b', &['\u30ab', '\u30a4', '\u30ea']), ('\u330c', &['\u30ab', '\u30e9',
+ '\u30c3', '\u30c8']), ('\u330d', &['\u30ab', '\u30ed', '\u30ea', '\u30fc']), ('\u330e',
+ &['\u30ac', '\u30ed', '\u30f3']), ('\u330f', &['\u30ac', '\u30f3', '\u30de']), ('\u3310',
+ &['\u30ae', '\u30ac']), ('\u3311', &['\u30ae', '\u30cb', '\u30fc']), ('\u3312', &['\u30ad',
+ '\u30e5', '\u30ea', '\u30fc']), ('\u3313', &['\u30ae', '\u30eb', '\u30c0', '\u30fc']),
+ ('\u3314', &['\u30ad', '\u30ed']), ('\u3315', &['\u30ad', '\u30ed', '\u30b0', '\u30e9',
+ '\u30e0']), ('\u3316', &['\u30ad', '\u30ed', '\u30e1', '\u30fc', '\u30c8', '\u30eb']),
+ ('\u3317', &['\u30ad', '\u30ed', '\u30ef', '\u30c3', '\u30c8']), ('\u3318', &['\u30b0',
+ '\u30e9', '\u30e0']), ('\u3319', &['\u30b0', '\u30e9', '\u30e0', '\u30c8', '\u30f3']),
+ ('\u331a', &['\u30af', '\u30eb', '\u30bc', '\u30a4', '\u30ed']), ('\u331b', &['\u30af',
+ '\u30ed', '\u30fc', '\u30cd']), ('\u331c', &['\u30b1', '\u30fc', '\u30b9']), ('\u331d',
+ &['\u30b3', '\u30eb', '\u30ca']), ('\u331e', &['\u30b3', '\u30fc', '\u30dd']), ('\u331f',
+ &['\u30b5', '\u30a4', '\u30af', '\u30eb']), ('\u3320', &['\u30b5', '\u30f3', '\u30c1',
+ '\u30fc', '\u30e0']), ('\u3321', &['\u30b7', '\u30ea', '\u30f3', '\u30b0']), ('\u3322',
+ &['\u30bb', '\u30f3', '\u30c1']), ('\u3323', &['\u30bb', '\u30f3', '\u30c8']), ('\u3324',
+ &['\u30c0', '\u30fc', '\u30b9']), ('\u3325', &['\u30c7', '\u30b7']), ('\u3326', &['\u30c9',
+ '\u30eb']), ('\u3327', &['\u30c8', '\u30f3']), ('\u3328', &['\u30ca', '\u30ce']), ('\u3329',
+ &['\u30ce', '\u30c3', '\u30c8']), ('\u332a', &['\u30cf', '\u30a4', '\u30c4']), ('\u332b',
+ &['\u30d1', '\u30fc', '\u30bb', '\u30f3', '\u30c8']), ('\u332c', &['\u30d1', '\u30fc',
+ '\u30c4']), ('\u332d', &['\u30d0', '\u30fc', '\u30ec', '\u30eb']), ('\u332e', &['\u30d4',
+ '\u30a2', '\u30b9', '\u30c8', '\u30eb']), ('\u332f', &['\u30d4', '\u30af', '\u30eb']),
+ ('\u3330', &['\u30d4', '\u30b3']), ('\u3331', &['\u30d3', '\u30eb']), ('\u3332', &['\u30d5',
+ '\u30a1', '\u30e9', '\u30c3', '\u30c9']), ('\u3333', &['\u30d5', '\u30a3', '\u30fc',
+ '\u30c8']), ('\u3334', &['\u30d6', '\u30c3', '\u30b7', '\u30a7', '\u30eb']), ('\u3335',
+ &['\u30d5', '\u30e9', '\u30f3']), ('\u3336', &['\u30d8', '\u30af', '\u30bf', '\u30fc',
+ '\u30eb']), ('\u3337', &['\u30da', '\u30bd']), ('\u3338', &['\u30da', '\u30cb', '\u30d2']),
+ ('\u3339', &['\u30d8', '\u30eb', '\u30c4']), ('\u333a', &['\u30da', '\u30f3', '\u30b9']),
+ ('\u333b', &['\u30da', '\u30fc', '\u30b8']), ('\u333c', &['\u30d9', '\u30fc', '\u30bf']),
+ ('\u333d', &['\u30dd', '\u30a4', '\u30f3', '\u30c8']), ('\u333e', &['\u30dc', '\u30eb',
+ '\u30c8']), ('\u333f', &['\u30db', '\u30f3']), ('\u3340', &['\u30dd', '\u30f3', '\u30c9']),
+ ('\u3341', &['\u30db', '\u30fc', '\u30eb']), ('\u3342', &['\u30db', '\u30fc', '\u30f3']),
+ ('\u3343', &['\u30de', '\u30a4', '\u30af', '\u30ed']), ('\u3344', &['\u30de', '\u30a4',
+ '\u30eb']), ('\u3345', &['\u30de', '\u30c3', '\u30cf']), ('\u3346', &['\u30de', '\u30eb',
+ '\u30af']), ('\u3347', &['\u30de', '\u30f3', '\u30b7', '\u30e7', '\u30f3']), ('\u3348',
+ &['\u30df', '\u30af', '\u30ed', '\u30f3']), ('\u3349', &['\u30df', '\u30ea']), ('\u334a',
+ &['\u30df', '\u30ea', '\u30d0', '\u30fc', '\u30eb']), ('\u334b', &['\u30e1', '\u30ac']),
+ ('\u334c', &['\u30e1', '\u30ac', '\u30c8', '\u30f3']), ('\u334d', &['\u30e1', '\u30fc',
+ '\u30c8', '\u30eb']), ('\u334e', &['\u30e4', '\u30fc', '\u30c9']), ('\u334f', &['\u30e4',
+ '\u30fc', '\u30eb']), ('\u3350', &['\u30e6', '\u30a2', '\u30f3']), ('\u3351', &['\u30ea',
+ '\u30c3', '\u30c8', '\u30eb']), ('\u3352', &['\u30ea', '\u30e9']), ('\u3353', &['\u30eb',
+ '\u30d4', '\u30fc']), ('\u3354', &['\u30eb', '\u30fc', '\u30d6', '\u30eb']), ('\u3355',
+ &['\u30ec', '\u30e0']), ('\u3356', &['\u30ec', '\u30f3', '\u30c8', '\u30b2', '\u30f3']),
+ ('\u3357', &['\u30ef', '\u30c3', '\u30c8']), ('\u3358', &['\x30', '\u70b9']), ('\u3359',
+ &['\x31', '\u70b9']), ('\u335a', &['\x32', '\u70b9']), ('\u335b', &['\x33', '\u70b9']),
+ ('\u335c', &['\x34', '\u70b9']), ('\u335d', &['\x35', '\u70b9']), ('\u335e', &['\x36',
+ '\u70b9']), ('\u335f', &['\x37', '\u70b9']), ('\u3360', &['\x38', '\u70b9']), ('\u3361',
+ &['\x39', '\u70b9']), ('\u3362', &['\x31', '\x30', '\u70b9']), ('\u3363', &['\x31', '\x31',
+ '\u70b9']), ('\u3364', &['\x31', '\x32', '\u70b9']), ('\u3365', &['\x31', '\x33',
+ '\u70b9']), ('\u3366', &['\x31', '\x34', '\u70b9']), ('\u3367', &['\x31', '\x35',
+ '\u70b9']), ('\u3368', &['\x31', '\x36', '\u70b9']), ('\u3369', &['\x31', '\x37',
+ '\u70b9']), ('\u336a', &['\x31', '\x38', '\u70b9']), ('\u336b', &['\x31', '\x39',
+ '\u70b9']), ('\u336c', &['\x32', '\x30', '\u70b9']), ('\u336d', &['\x32', '\x31',
+ '\u70b9']), ('\u336e', &['\x32', '\x32', '\u70b9']), ('\u336f', &['\x32', '\x33',
+ '\u70b9']), ('\u3370', &['\x32', '\x34', '\u70b9']), ('\u3371', &['\x68', '\x50', '\x61']),
+ ('\u3372', &['\x64', '\x61']), ('\u3373', &['\x41', '\x55']), ('\u3374', &['\x62', '\x61',
+ '\x72']), ('\u3375', &['\x6f', '\x56']), ('\u3376', &['\x70', '\x63']), ('\u3377', &['\x64',
+ '\x6d']), ('\u3378', &['\x64', '\x6d', '\xb2']), ('\u3379', &['\x64', '\x6d', '\xb3']),
+ ('\u337a', &['\x49', '\x55']), ('\u337b', &['\u5e73', '\u6210']), ('\u337c', &['\u662d',
+ '\u548c']), ('\u337d', &['\u5927', '\u6b63']), ('\u337e', &['\u660e', '\u6cbb']), ('\u337f',
+ &['\u682a', '\u5f0f', '\u4f1a', '\u793e']), ('\u3380', &['\x70', '\x41']), ('\u3381',
+ &['\x6e', '\x41']), ('\u3382', &['\u03bc', '\x41']), ('\u3383', &['\x6d', '\x41']),
+ ('\u3384', &['\x6b', '\x41']), ('\u3385', &['\x4b', '\x42']), ('\u3386', &['\x4d', '\x42']),
+ ('\u3387', &['\x47', '\x42']), ('\u3388', &['\x63', '\x61', '\x6c']), ('\u3389', &['\x6b',
+ '\x63', '\x61', '\x6c']), ('\u338a', &['\x70', '\x46']), ('\u338b', &['\x6e', '\x46']),
+ ('\u338c', &['\u03bc', '\x46']), ('\u338d', &['\u03bc', '\x67']), ('\u338e', &['\x6d',
+ '\x67']), ('\u338f', &['\x6b', '\x67']), ('\u3390', &['\x48', '\x7a']), ('\u3391', &['\x6b',
+ '\x48', '\x7a']), ('\u3392', &['\x4d', '\x48', '\x7a']), ('\u3393', &['\x47', '\x48',
+ '\x7a']), ('\u3394', &['\x54', '\x48', '\x7a']), ('\u3395', &['\u03bc', '\u2113']),
+ ('\u3396', &['\x6d', '\u2113']), ('\u3397', &['\x64', '\u2113']), ('\u3398', &['\x6b',
+ '\u2113']), ('\u3399', &['\x66', '\x6d']), ('\u339a', &['\x6e', '\x6d']), ('\u339b',
+ &['\u03bc', '\x6d']), ('\u339c', &['\x6d', '\x6d']), ('\u339d', &['\x63', '\x6d']),
+ ('\u339e', &['\x6b', '\x6d']), ('\u339f', &['\x6d', '\x6d', '\xb2']), ('\u33a0', &['\x63',
+ '\x6d', '\xb2']), ('\u33a1', &['\x6d', '\xb2']), ('\u33a2', &['\x6b', '\x6d', '\xb2']),
+ ('\u33a3', &['\x6d', '\x6d', '\xb3']), ('\u33a4', &['\x63', '\x6d', '\xb3']), ('\u33a5',
+ &['\x6d', '\xb3']), ('\u33a6', &['\x6b', '\x6d', '\xb3']), ('\u33a7', &['\x6d', '\u2215',
+ '\x73']), ('\u33a8', &['\x6d', '\u2215', '\x73', '\xb2']), ('\u33a9', &['\x50', '\x61']),
+ ('\u33aa', &['\x6b', '\x50', '\x61']), ('\u33ab', &['\x4d', '\x50', '\x61']), ('\u33ac',
+ &['\x47', '\x50', '\x61']), ('\u33ad', &['\x72', '\x61', '\x64']), ('\u33ae', &['\x72',
+ '\x61', '\x64', '\u2215', '\x73']), ('\u33af', &['\x72', '\x61', '\x64', '\u2215', '\x73',
+ '\xb2']), ('\u33b0', &['\x70', '\x73']), ('\u33b1', &['\x6e', '\x73']), ('\u33b2',
+ &['\u03bc', '\x73']), ('\u33b3', &['\x6d', '\x73']), ('\u33b4', &['\x70', '\x56']),
+ ('\u33b5', &['\x6e', '\x56']), ('\u33b6', &['\u03bc', '\x56']), ('\u33b7', &['\x6d',
+ '\x56']), ('\u33b8', &['\x6b', '\x56']), ('\u33b9', &['\x4d', '\x56']), ('\u33ba', &['\x70',
+ '\x57']), ('\u33bb', &['\x6e', '\x57']), ('\u33bc', &['\u03bc', '\x57']), ('\u33bd',
+ &['\x6d', '\x57']), ('\u33be', &['\x6b', '\x57']), ('\u33bf', &['\x4d', '\x57']), ('\u33c0',
+ &['\x6b', '\u03a9']), ('\u33c1', &['\x4d', '\u03a9']), ('\u33c2', &['\x61', '\x2e', '\x6d',
+ '\x2e']), ('\u33c3', &['\x42', '\x71']), ('\u33c4', &['\x63', '\x63']), ('\u33c5', &['\x63',
+ '\x64']), ('\u33c6', &['\x43', '\u2215', '\x6b', '\x67']), ('\u33c7', &['\x43', '\x6f',
+ '\x2e']), ('\u33c8', &['\x64', '\x42']), ('\u33c9', &['\x47', '\x79']), ('\u33ca', &['\x68',
+ '\x61']), ('\u33cb', &['\x48', '\x50']), ('\u33cc', &['\x69', '\x6e']), ('\u33cd', &['\x4b',
+ '\x4b']), ('\u33ce', &['\x4b', '\x4d']), ('\u33cf', &['\x6b', '\x74']), ('\u33d0', &['\x6c',
+ '\x6d']), ('\u33d1', &['\x6c', '\x6e']), ('\u33d2', &['\x6c', '\x6f', '\x67']), ('\u33d3',
+ &['\x6c', '\x78']), ('\u33d4', &['\x6d', '\x62']), ('\u33d5', &['\x6d', '\x69', '\x6c']),
+ ('\u33d6', &['\x6d', '\x6f', '\x6c']), ('\u33d7', &['\x50', '\x48']), ('\u33d8', &['\x70',
+ '\x2e', '\x6d', '\x2e']), ('\u33d9', &['\x50', '\x50', '\x4d']), ('\u33da', &['\x50',
+ '\x52']), ('\u33db', &['\x73', '\x72']), ('\u33dc', &['\x53', '\x76']), ('\u33dd', &['\x57',
+ '\x62']), ('\u33de', &['\x56', '\u2215', '\x6d']), ('\u33df', &['\x41', '\u2215', '\x6d']),
+ ('\u33e0', &['\x31', '\u65e5']), ('\u33e1', &['\x32', '\u65e5']), ('\u33e2', &['\x33',
+ '\u65e5']), ('\u33e3', &['\x34', '\u65e5']), ('\u33e4', &['\x35', '\u65e5']), ('\u33e5',
+ &['\x36', '\u65e5']), ('\u33e6', &['\x37', '\u65e5']), ('\u33e7', &['\x38', '\u65e5']),
+ ('\u33e8', &['\x39', '\u65e5']), ('\u33e9', &['\x31', '\x30', '\u65e5']), ('\u33ea',
+ &['\x31', '\x31', '\u65e5']), ('\u33eb', &['\x31', '\x32', '\u65e5']), ('\u33ec', &['\x31',
+ '\x33', '\u65e5']), ('\u33ed', &['\x31', '\x34', '\u65e5']), ('\u33ee', &['\x31', '\x35',
+ '\u65e5']), ('\u33ef', &['\x31', '\x36', '\u65e5']), ('\u33f0', &['\x31', '\x37',
+ '\u65e5']), ('\u33f1', &['\x31', '\x38', '\u65e5']), ('\u33f2', &['\x31', '\x39',
+ '\u65e5']), ('\u33f3', &['\x32', '\x30', '\u65e5']), ('\u33f4', &['\x32', '\x31',
+ '\u65e5']), ('\u33f5', &['\x32', '\x32', '\u65e5']), ('\u33f6', &['\x32', '\x33',
+ '\u65e5']), ('\u33f7', &['\x32', '\x34', '\u65e5']), ('\u33f8', &['\x32', '\x35',
+ '\u65e5']), ('\u33f9', &['\x32', '\x36', '\u65e5']), ('\u33fa', &['\x32', '\x37',
+ '\u65e5']), ('\u33fb', &['\x32', '\x38', '\u65e5']), ('\u33fc', &['\x32', '\x39',
+ '\u65e5']), ('\u33fd', &['\x33', '\x30', '\u65e5']), ('\u33fe', &['\x33', '\x31',
+ '\u65e5']), ('\u33ff', &['\x67', '\x61', '\x6c']), ('\ua69c', &['\u044a']), ('\ua69d',
+ &['\u044c']), ('\ua770', &['\ua76f']), ('\ua7f8', &['\u0126']), ('\ua7f9', &['\u0153']),
+ ('\uab5c', &['\ua727']), ('\uab5d', &['\uab37']), ('\uab5e', &['\u026b']), ('\uab5f',
+ &['\uab52']), ('\ufb00', &['\x66', '\x66']), ('\ufb01', &['\x66', '\x69']), ('\ufb02',
+ &['\x66', '\x6c']), ('\ufb03', &['\x66', '\x66', '\x69']), ('\ufb04', &['\x66', '\x66',
+ '\x6c']), ('\ufb05', &['\u017f', '\x74']), ('\ufb06', &['\x73', '\x74']), ('\ufb13',
+ &['\u0574', '\u0576']), ('\ufb14', &['\u0574', '\u0565']), ('\ufb15', &['\u0574',
+ '\u056b']), ('\ufb16', &['\u057e', '\u0576']), ('\ufb17', &['\u0574', '\u056d']), ('\ufb20',
+ &['\u05e2']), ('\ufb21', &['\u05d0']), ('\ufb22', &['\u05d3']), ('\ufb23', &['\u05d4']),
+ ('\ufb24', &['\u05db']), ('\ufb25', &['\u05dc']), ('\ufb26', &['\u05dd']), ('\ufb27',
+ &['\u05e8']), ('\ufb28', &['\u05ea']), ('\ufb29', &['\x2b']), ('\ufb4f', &['\u05d0',
+ '\u05dc']), ('\ufb50', &['\u0671']), ('\ufb51', &['\u0671']), ('\ufb52', &['\u067b']),
+ ('\ufb53', &['\u067b']), ('\ufb54', &['\u067b']), ('\ufb55', &['\u067b']), ('\ufb56',
+ &['\u067e']), ('\ufb57', &['\u067e']), ('\ufb58', &['\u067e']), ('\ufb59', &['\u067e']),
+ ('\ufb5a', &['\u0680']), ('\ufb5b', &['\u0680']), ('\ufb5c', &['\u0680']), ('\ufb5d',
+ &['\u0680']), ('\ufb5e', &['\u067a']), ('\ufb5f', &['\u067a']), ('\ufb60', &['\u067a']),
+ ('\ufb61', &['\u067a']), ('\ufb62', &['\u067f']), ('\ufb63', &['\u067f']), ('\ufb64',
+ &['\u067f']), ('\ufb65', &['\u067f']), ('\ufb66', &['\u0679']), ('\ufb67', &['\u0679']),
+ ('\ufb68', &['\u0679']), ('\ufb69', &['\u0679']), ('\ufb6a', &['\u06a4']), ('\ufb6b',
+ &['\u06a4']), ('\ufb6c', &['\u06a4']), ('\ufb6d', &['\u06a4']), ('\ufb6e', &['\u06a6']),
+ ('\ufb6f', &['\u06a6']), ('\ufb70', &['\u06a6']), ('\ufb71', &['\u06a6']), ('\ufb72',
+ &['\u0684']), ('\ufb73', &['\u0684']), ('\ufb74', &['\u0684']), ('\ufb75', &['\u0684']),
+ ('\ufb76', &['\u0683']), ('\ufb77', &['\u0683']), ('\ufb78', &['\u0683']), ('\ufb79',
+ &['\u0683']), ('\ufb7a', &['\u0686']), ('\ufb7b', &['\u0686']), ('\ufb7c', &['\u0686']),
+ ('\ufb7d', &['\u0686']), ('\ufb7e', &['\u0687']), ('\ufb7f', &['\u0687']), ('\ufb80',
+ &['\u0687']), ('\ufb81', &['\u0687']), ('\ufb82', &['\u068d']), ('\ufb83', &['\u068d']),
+ ('\ufb84', &['\u068c']), ('\ufb85', &['\u068c']), ('\ufb86', &['\u068e']), ('\ufb87',
+ &['\u068e']), ('\ufb88', &['\u0688']), ('\ufb89', &['\u0688']), ('\ufb8a', &['\u0698']),
+ ('\ufb8b', &['\u0698']), ('\ufb8c', &['\u0691']), ('\ufb8d', &['\u0691']), ('\ufb8e',
+ &['\u06a9']), ('\ufb8f', &['\u06a9']), ('\ufb90', &['\u06a9']), ('\ufb91', &['\u06a9']),
+ ('\ufb92', &['\u06af']), ('\ufb93', &['\u06af']), ('\ufb94', &['\u06af']), ('\ufb95',
+ &['\u06af']), ('\ufb96', &['\u06b3']), ('\ufb97', &['\u06b3']), ('\ufb98', &['\u06b3']),
+ ('\ufb99', &['\u06b3']), ('\ufb9a', &['\u06b1']), ('\ufb9b', &['\u06b1']), ('\ufb9c',
+ &['\u06b1']), ('\ufb9d', &['\u06b1']), ('\ufb9e', &['\u06ba']), ('\ufb9f', &['\u06ba']),
+ ('\ufba0', &['\u06bb']), ('\ufba1', &['\u06bb']), ('\ufba2', &['\u06bb']), ('\ufba3',
+ &['\u06bb']), ('\ufba4', &['\u06c0']), ('\ufba5', &['\u06c0']), ('\ufba6', &['\u06c1']),
+ ('\ufba7', &['\u06c1']), ('\ufba8', &['\u06c1']), ('\ufba9', &['\u06c1']), ('\ufbaa',
+ &['\u06be']), ('\ufbab', &['\u06be']), ('\ufbac', &['\u06be']), ('\ufbad', &['\u06be']),
+ ('\ufbae', &['\u06d2']), ('\ufbaf', &['\u06d2']), ('\ufbb0', &['\u06d3']), ('\ufbb1',
+ &['\u06d3']), ('\ufbd3', &['\u06ad']), ('\ufbd4', &['\u06ad']), ('\ufbd5', &['\u06ad']),
+ ('\ufbd6', &['\u06ad']), ('\ufbd7', &['\u06c7']), ('\ufbd8', &['\u06c7']), ('\ufbd9',
+ &['\u06c6']), ('\ufbda', &['\u06c6']), ('\ufbdb', &['\u06c8']), ('\ufbdc', &['\u06c8']),
+ ('\ufbdd', &['\u0677']), ('\ufbde', &['\u06cb']), ('\ufbdf', &['\u06cb']), ('\ufbe0',
+ &['\u06c5']), ('\ufbe1', &['\u06c5']), ('\ufbe2', &['\u06c9']), ('\ufbe3', &['\u06c9']),
+ ('\ufbe4', &['\u06d0']), ('\ufbe5', &['\u06d0']), ('\ufbe6', &['\u06d0']), ('\ufbe7',
+ &['\u06d0']), ('\ufbe8', &['\u0649']), ('\ufbe9', &['\u0649']), ('\ufbea', &['\u0626',
+ '\u0627']), ('\ufbeb', &['\u0626', '\u0627']), ('\ufbec', &['\u0626', '\u06d5']), ('\ufbed',
+ &['\u0626', '\u06d5']), ('\ufbee', &['\u0626', '\u0648']), ('\ufbef', &['\u0626',
+ '\u0648']), ('\ufbf0', &['\u0626', '\u06c7']), ('\ufbf1', &['\u0626', '\u06c7']), ('\ufbf2',
+ &['\u0626', '\u06c6']), ('\ufbf3', &['\u0626', '\u06c6']), ('\ufbf4', &['\u0626',
+ '\u06c8']), ('\ufbf5', &['\u0626', '\u06c8']), ('\ufbf6', &['\u0626', '\u06d0']), ('\ufbf7',
+ &['\u0626', '\u06d0']), ('\ufbf8', &['\u0626', '\u06d0']), ('\ufbf9', &['\u0626',
+ '\u0649']), ('\ufbfa', &['\u0626', '\u0649']), ('\ufbfb', &['\u0626', '\u0649']), ('\ufbfc',
+ &['\u06cc']), ('\ufbfd', &['\u06cc']), ('\ufbfe', &['\u06cc']), ('\ufbff', &['\u06cc']),
+ ('\ufc00', &['\u0626', '\u062c']), ('\ufc01', &['\u0626', '\u062d']), ('\ufc02', &['\u0626',
+ '\u0645']), ('\ufc03', &['\u0626', '\u0649']), ('\ufc04', &['\u0626', '\u064a']), ('\ufc05',
+ &['\u0628', '\u062c']), ('\ufc06', &['\u0628', '\u062d']), ('\ufc07', &['\u0628',
+ '\u062e']), ('\ufc08', &['\u0628', '\u0645']), ('\ufc09', &['\u0628', '\u0649']), ('\ufc0a',
+ &['\u0628', '\u064a']), ('\ufc0b', &['\u062a', '\u062c']), ('\ufc0c', &['\u062a',
+ '\u062d']), ('\ufc0d', &['\u062a', '\u062e']), ('\ufc0e', &['\u062a', '\u0645']), ('\ufc0f',
+ &['\u062a', '\u0649']), ('\ufc10', &['\u062a', '\u064a']), ('\ufc11', &['\u062b',
+ '\u062c']), ('\ufc12', &['\u062b', '\u0645']), ('\ufc13', &['\u062b', '\u0649']), ('\ufc14',
+ &['\u062b', '\u064a']), ('\ufc15', &['\u062c', '\u062d']), ('\ufc16', &['\u062c',
+ '\u0645']), ('\ufc17', &['\u062d', '\u062c']), ('\ufc18', &['\u062d', '\u0645']), ('\ufc19',
+ &['\u062e', '\u062c']), ('\ufc1a', &['\u062e', '\u062d']), ('\ufc1b', &['\u062e',
+ '\u0645']), ('\ufc1c', &['\u0633', '\u062c']), ('\ufc1d', &['\u0633', '\u062d']), ('\ufc1e',
+ &['\u0633', '\u062e']), ('\ufc1f', &['\u0633', '\u0645']), ('\ufc20', &['\u0635',
+ '\u062d']), ('\ufc21', &['\u0635', '\u0645']), ('\ufc22', &['\u0636', '\u062c']), ('\ufc23',
+ &['\u0636', '\u062d']), ('\ufc24', &['\u0636', '\u062e']), ('\ufc25', &['\u0636',
+ '\u0645']), ('\ufc26', &['\u0637', '\u062d']), ('\ufc27', &['\u0637', '\u0645']), ('\ufc28',
+ &['\u0638', '\u0645']), ('\ufc29', &['\u0639', '\u062c']), ('\ufc2a', &['\u0639',
+ '\u0645']), ('\ufc2b', &['\u063a', '\u062c']), ('\ufc2c', &['\u063a', '\u0645']), ('\ufc2d',
+ &['\u0641', '\u062c']), ('\ufc2e', &['\u0641', '\u062d']), ('\ufc2f', &['\u0641',
+ '\u062e']), ('\ufc30', &['\u0641', '\u0645']), ('\ufc31', &['\u0641', '\u0649']), ('\ufc32',
+ &['\u0641', '\u064a']), ('\ufc33', &['\u0642', '\u062d']), ('\ufc34', &['\u0642',
+ '\u0645']), ('\ufc35', &['\u0642', '\u0649']), ('\ufc36', &['\u0642', '\u064a']), ('\ufc37',
+ &['\u0643', '\u0627']), ('\ufc38', &['\u0643', '\u062c']), ('\ufc39', &['\u0643',
+ '\u062d']), ('\ufc3a', &['\u0643', '\u062e']), ('\ufc3b', &['\u0643', '\u0644']), ('\ufc3c',
+ &['\u0643', '\u0645']), ('\ufc3d', &['\u0643', '\u0649']), ('\ufc3e', &['\u0643',
+ '\u064a']), ('\ufc3f', &['\u0644', '\u062c']), ('\ufc40', &['\u0644', '\u062d']), ('\ufc41',
+ &['\u0644', '\u062e']), ('\ufc42', &['\u0644', '\u0645']), ('\ufc43', &['\u0644',
+ '\u0649']), ('\ufc44', &['\u0644', '\u064a']), ('\ufc45', &['\u0645', '\u062c']), ('\ufc46',
+ &['\u0645', '\u062d']), ('\ufc47', &['\u0645', '\u062e']), ('\ufc48', &['\u0645',
+ '\u0645']), ('\ufc49', &['\u0645', '\u0649']), ('\ufc4a', &['\u0645', '\u064a']), ('\ufc4b',
+ &['\u0646', '\u062c']), ('\ufc4c', &['\u0646', '\u062d']), ('\ufc4d', &['\u0646',
+ '\u062e']), ('\ufc4e', &['\u0646', '\u0645']), ('\ufc4f', &['\u0646', '\u0649']), ('\ufc50',
+ &['\u0646', '\u064a']), ('\ufc51', &['\u0647', '\u062c']), ('\ufc52', &['\u0647',
+ '\u0645']), ('\ufc53', &['\u0647', '\u0649']), ('\ufc54', &['\u0647', '\u064a']), ('\ufc55',
+ &['\u064a', '\u062c']), ('\ufc56', &['\u064a', '\u062d']), ('\ufc57', &['\u064a',
+ '\u062e']), ('\ufc58', &['\u064a', '\u0645']), ('\ufc59', &['\u064a', '\u0649']), ('\ufc5a',
+ &['\u064a', '\u064a']), ('\ufc5b', &['\u0630', '\u0670']), ('\ufc5c', &['\u0631',
+ '\u0670']), ('\ufc5d', &['\u0649', '\u0670']), ('\ufc5e', &['\x20', '\u064c', '\u0651']),
+ ('\ufc5f', &['\x20', '\u064d', '\u0651']), ('\ufc60', &['\x20', '\u064e', '\u0651']),
+ ('\ufc61', &['\x20', '\u064f', '\u0651']), ('\ufc62', &['\x20', '\u0650', '\u0651']),
+ ('\ufc63', &['\x20', '\u0651', '\u0670']), ('\ufc64', &['\u0626', '\u0631']), ('\ufc65',
+ &['\u0626', '\u0632']), ('\ufc66', &['\u0626', '\u0645']), ('\ufc67', &['\u0626',
+ '\u0646']), ('\ufc68', &['\u0626', '\u0649']), ('\ufc69', &['\u0626', '\u064a']), ('\ufc6a',
+ &['\u0628', '\u0631']), ('\ufc6b', &['\u0628', '\u0632']), ('\ufc6c', &['\u0628',
+ '\u0645']), ('\ufc6d', &['\u0628', '\u0646']), ('\ufc6e', &['\u0628', '\u0649']), ('\ufc6f',
+ &['\u0628', '\u064a']), ('\ufc70', &['\u062a', '\u0631']), ('\ufc71', &['\u062a',
+ '\u0632']), ('\ufc72', &['\u062a', '\u0645']), ('\ufc73', &['\u062a', '\u0646']), ('\ufc74',
+ &['\u062a', '\u0649']), ('\ufc75', &['\u062a', '\u064a']), ('\ufc76', &['\u062b',
+ '\u0631']), ('\ufc77', &['\u062b', '\u0632']), ('\ufc78', &['\u062b', '\u0645']), ('\ufc79',
+ &['\u062b', '\u0646']), ('\ufc7a', &['\u062b', '\u0649']), ('\ufc7b', &['\u062b',
+ '\u064a']), ('\ufc7c', &['\u0641', '\u0649']), ('\ufc7d', &['\u0641', '\u064a']), ('\ufc7e',
+ &['\u0642', '\u0649']), ('\ufc7f', &['\u0642', '\u064a']), ('\ufc80', &['\u0643',
+ '\u0627']), ('\ufc81', &['\u0643', '\u0644']), ('\ufc82', &['\u0643', '\u0645']), ('\ufc83',
+ &['\u0643', '\u0649']), ('\ufc84', &['\u0643', '\u064a']), ('\ufc85', &['\u0644',
+ '\u0645']), ('\ufc86', &['\u0644', '\u0649']), ('\ufc87', &['\u0644', '\u064a']), ('\ufc88',
+ &['\u0645', '\u0627']), ('\ufc89', &['\u0645', '\u0645']), ('\ufc8a', &['\u0646',
+ '\u0631']), ('\ufc8b', &['\u0646', '\u0632']), ('\ufc8c', &['\u0646', '\u0645']), ('\ufc8d',
+ &['\u0646', '\u0646']), ('\ufc8e', &['\u0646', '\u0649']), ('\ufc8f', &['\u0646',
+ '\u064a']), ('\ufc90', &['\u0649', '\u0670']), ('\ufc91', &['\u064a', '\u0631']), ('\ufc92',
+ &['\u064a', '\u0632']), ('\ufc93', &['\u064a', '\u0645']), ('\ufc94', &['\u064a',
+ '\u0646']), ('\ufc95', &['\u064a', '\u0649']), ('\ufc96', &['\u064a', '\u064a']), ('\ufc97',
+ &['\u0626', '\u062c']), ('\ufc98', &['\u0626', '\u062d']), ('\ufc99', &['\u0626',
+ '\u062e']), ('\ufc9a', &['\u0626', '\u0645']), ('\ufc9b', &['\u0626', '\u0647']), ('\ufc9c',
+ &['\u0628', '\u062c']), ('\ufc9d', &['\u0628', '\u062d']), ('\ufc9e', &['\u0628',
+ '\u062e']), ('\ufc9f', &['\u0628', '\u0645']), ('\ufca0', &['\u0628', '\u0647']), ('\ufca1',
+ &['\u062a', '\u062c']), ('\ufca2', &['\u062a', '\u062d']), ('\ufca3', &['\u062a',
+ '\u062e']), ('\ufca4', &['\u062a', '\u0645']), ('\ufca5', &['\u062a', '\u0647']), ('\ufca6',
+ &['\u062b', '\u0645']), ('\ufca7', &['\u062c', '\u062d']), ('\ufca8', &['\u062c',
+ '\u0645']), ('\ufca9', &['\u062d', '\u062c']), ('\ufcaa', &['\u062d', '\u0645']), ('\ufcab',
+ &['\u062e', '\u062c']), ('\ufcac', &['\u062e', '\u0645']), ('\ufcad', &['\u0633',
+ '\u062c']), ('\ufcae', &['\u0633', '\u062d']), ('\ufcaf', &['\u0633', '\u062e']), ('\ufcb0',
+ &['\u0633', '\u0645']), ('\ufcb1', &['\u0635', '\u062d']), ('\ufcb2', &['\u0635',
+ '\u062e']), ('\ufcb3', &['\u0635', '\u0645']), ('\ufcb4', &['\u0636', '\u062c']), ('\ufcb5',
+ &['\u0636', '\u062d']), ('\ufcb6', &['\u0636', '\u062e']), ('\ufcb7', &['\u0636',
+ '\u0645']), ('\ufcb8', &['\u0637', '\u062d']), ('\ufcb9', &['\u0638', '\u0645']), ('\ufcba',
+ &['\u0639', '\u062c']), ('\ufcbb', &['\u0639', '\u0645']), ('\ufcbc', &['\u063a',
+ '\u062c']), ('\ufcbd', &['\u063a', '\u0645']), ('\ufcbe', &['\u0641', '\u062c']), ('\ufcbf',
+ &['\u0641', '\u062d']), ('\ufcc0', &['\u0641', '\u062e']), ('\ufcc1', &['\u0641',
+ '\u0645']), ('\ufcc2', &['\u0642', '\u062d']), ('\ufcc3', &['\u0642', '\u0645']), ('\ufcc4',
+ &['\u0643', '\u062c']), ('\ufcc5', &['\u0643', '\u062d']), ('\ufcc6', &['\u0643',
+ '\u062e']), ('\ufcc7', &['\u0643', '\u0644']), ('\ufcc8', &['\u0643', '\u0645']), ('\ufcc9',
+ &['\u0644', '\u062c']), ('\ufcca', &['\u0644', '\u062d']), ('\ufccb', &['\u0644',
+ '\u062e']), ('\ufccc', &['\u0644', '\u0645']), ('\ufccd', &['\u0644', '\u0647']), ('\ufcce',
+ &['\u0645', '\u062c']), ('\ufccf', &['\u0645', '\u062d']), ('\ufcd0', &['\u0645',
+ '\u062e']), ('\ufcd1', &['\u0645', '\u0645']), ('\ufcd2', &['\u0646', '\u062c']), ('\ufcd3',
+ &['\u0646', '\u062d']), ('\ufcd4', &['\u0646', '\u062e']), ('\ufcd5', &['\u0646',
+ '\u0645']), ('\ufcd6', &['\u0646', '\u0647']), ('\ufcd7', &['\u0647', '\u062c']), ('\ufcd8',
+ &['\u0647', '\u0645']), ('\ufcd9', &['\u0647', '\u0670']), ('\ufcda', &['\u064a',
+ '\u062c']), ('\ufcdb', &['\u064a', '\u062d']), ('\ufcdc', &['\u064a', '\u062e']), ('\ufcdd',
+ &['\u064a', '\u0645']), ('\ufcde', &['\u064a', '\u0647']), ('\ufcdf', &['\u0626',
+ '\u0645']), ('\ufce0', &['\u0626', '\u0647']), ('\ufce1', &['\u0628', '\u0645']), ('\ufce2',
+ &['\u0628', '\u0647']), ('\ufce3', &['\u062a', '\u0645']), ('\ufce4', &['\u062a',
+ '\u0647']), ('\ufce5', &['\u062b', '\u0645']), ('\ufce6', &['\u062b', '\u0647']), ('\ufce7',
+ &['\u0633', '\u0645']), ('\ufce8', &['\u0633', '\u0647']), ('\ufce9', &['\u0634',
+ '\u0645']), ('\ufcea', &['\u0634', '\u0647']), ('\ufceb', &['\u0643', '\u0644']), ('\ufcec',
+ &['\u0643', '\u0645']), ('\ufced', &['\u0644', '\u0645']), ('\ufcee', &['\u0646',
+ '\u0645']), ('\ufcef', &['\u0646', '\u0647']), ('\ufcf0', &['\u064a', '\u0645']), ('\ufcf1',
+ &['\u064a', '\u0647']), ('\ufcf2', &['\u0640', '\u064e', '\u0651']), ('\ufcf3', &['\u0640',
+ '\u064f', '\u0651']), ('\ufcf4', &['\u0640', '\u0650', '\u0651']), ('\ufcf5', &['\u0637',
+ '\u0649']), ('\ufcf6', &['\u0637', '\u064a']), ('\ufcf7', &['\u0639', '\u0649']), ('\ufcf8',
+ &['\u0639', '\u064a']), ('\ufcf9', &['\u063a', '\u0649']), ('\ufcfa', &['\u063a',
+ '\u064a']), ('\ufcfb', &['\u0633', '\u0649']), ('\ufcfc', &['\u0633', '\u064a']), ('\ufcfd',
+ &['\u0634', '\u0649']), ('\ufcfe', &['\u0634', '\u064a']), ('\ufcff', &['\u062d',
+ '\u0649']), ('\ufd00', &['\u062d', '\u064a']), ('\ufd01', &['\u062c', '\u0649']), ('\ufd02',
+ &['\u062c', '\u064a']), ('\ufd03', &['\u062e', '\u0649']), ('\ufd04', &['\u062e',
+ '\u064a']), ('\ufd05', &['\u0635', '\u0649']), ('\ufd06', &['\u0635', '\u064a']), ('\ufd07',
+ &['\u0636', '\u0649']), ('\ufd08', &['\u0636', '\u064a']), ('\ufd09', &['\u0634',
+ '\u062c']), ('\ufd0a', &['\u0634', '\u062d']), ('\ufd0b', &['\u0634', '\u062e']), ('\ufd0c',
+ &['\u0634', '\u0645']), ('\ufd0d', &['\u0634', '\u0631']), ('\ufd0e', &['\u0633',
+ '\u0631']), ('\ufd0f', &['\u0635', '\u0631']), ('\ufd10', &['\u0636', '\u0631']), ('\ufd11',
+ &['\u0637', '\u0649']), ('\ufd12', &['\u0637', '\u064a']), ('\ufd13', &['\u0639',
+ '\u0649']), ('\ufd14', &['\u0639', '\u064a']), ('\ufd15', &['\u063a', '\u0649']), ('\ufd16',
+ &['\u063a', '\u064a']), ('\ufd17', &['\u0633', '\u0649']), ('\ufd18', &['\u0633',
+ '\u064a']), ('\ufd19', &['\u0634', '\u0649']), ('\ufd1a', &['\u0634', '\u064a']), ('\ufd1b',
+ &['\u062d', '\u0649']), ('\ufd1c', &['\u062d', '\u064a']), ('\ufd1d', &['\u062c',
+ '\u0649']), ('\ufd1e', &['\u062c', '\u064a']), ('\ufd1f', &['\u062e', '\u0649']), ('\ufd20',
+ &['\u062e', '\u064a']), ('\ufd21', &['\u0635', '\u0649']), ('\ufd22', &['\u0635',
+ '\u064a']), ('\ufd23', &['\u0636', '\u0649']), ('\ufd24', &['\u0636', '\u064a']), ('\ufd25',
+ &['\u0634', '\u062c']), ('\ufd26', &['\u0634', '\u062d']), ('\ufd27', &['\u0634',
+ '\u062e']), ('\ufd28', &['\u0634', '\u0645']), ('\ufd29', &['\u0634', '\u0631']), ('\ufd2a',
+ &['\u0633', '\u0631']), ('\ufd2b', &['\u0635', '\u0631']), ('\ufd2c', &['\u0636',
+ '\u0631']), ('\ufd2d', &['\u0634', '\u062c']), ('\ufd2e', &['\u0634', '\u062d']), ('\ufd2f',
+ &['\u0634', '\u062e']), ('\ufd30', &['\u0634', '\u0645']), ('\ufd31', &['\u0633',
+ '\u0647']), ('\ufd32', &['\u0634', '\u0647']), ('\ufd33', &['\u0637', '\u0645']), ('\ufd34',
+ &['\u0633', '\u062c']), ('\ufd35', &['\u0633', '\u062d']), ('\ufd36', &['\u0633',
+ '\u062e']), ('\ufd37', &['\u0634', '\u062c']), ('\ufd38', &['\u0634', '\u062d']), ('\ufd39',
+ &['\u0634', '\u062e']), ('\ufd3a', &['\u0637', '\u0645']), ('\ufd3b', &['\u0638',
+ '\u0645']), ('\ufd3c', &['\u0627', '\u064b']), ('\ufd3d', &['\u0627', '\u064b']), ('\ufd50',
+ &['\u062a', '\u062c', '\u0645']), ('\ufd51', &['\u062a', '\u062d', '\u062c']), ('\ufd52',
+ &['\u062a', '\u062d', '\u062c']), ('\ufd53', &['\u062a', '\u062d', '\u0645']), ('\ufd54',
+ &['\u062a', '\u062e', '\u0645']), ('\ufd55', &['\u062a', '\u0645', '\u062c']), ('\ufd56',
+ &['\u062a', '\u0645', '\u062d']), ('\ufd57', &['\u062a', '\u0645', '\u062e']), ('\ufd58',
+ &['\u062c', '\u0645', '\u062d']), ('\ufd59', &['\u062c', '\u0645', '\u062d']), ('\ufd5a',
+ &['\u062d', '\u0645', '\u064a']), ('\ufd5b', &['\u062d', '\u0645', '\u0649']), ('\ufd5c',
+ &['\u0633', '\u062d', '\u062c']), ('\ufd5d', &['\u0633', '\u062c', '\u062d']), ('\ufd5e',
+ &['\u0633', '\u062c', '\u0649']), ('\ufd5f', &['\u0633', '\u0645', '\u062d']), ('\ufd60',
+ &['\u0633', '\u0645', '\u062d']), ('\ufd61', &['\u0633', '\u0645', '\u062c']), ('\ufd62',
+ &['\u0633', '\u0645', '\u0645']), ('\ufd63', &['\u0633', '\u0645', '\u0645']), ('\ufd64',
+ &['\u0635', '\u062d', '\u062d']), ('\ufd65', &['\u0635', '\u062d', '\u062d']), ('\ufd66',
+ &['\u0635', '\u0645', '\u0645']), ('\ufd67', &['\u0634', '\u062d', '\u0645']), ('\ufd68',
+ &['\u0634', '\u062d', '\u0645']), ('\ufd69', &['\u0634', '\u062c', '\u064a']), ('\ufd6a',
+ &['\u0634', '\u0645', '\u062e']), ('\ufd6b', &['\u0634', '\u0645', '\u062e']), ('\ufd6c',
+ &['\u0634', '\u0645', '\u0645']), ('\ufd6d', &['\u0634', '\u0645', '\u0645']), ('\ufd6e',
+ &['\u0636', '\u062d', '\u0649']), ('\ufd6f', &['\u0636', '\u062e', '\u0645']), ('\ufd70',
+ &['\u0636', '\u062e', '\u0645']), ('\ufd71', &['\u0637', '\u0645', '\u062d']), ('\ufd72',
+ &['\u0637', '\u0645', '\u062d']), ('\ufd73', &['\u0637', '\u0645', '\u0645']), ('\ufd74',
+ &['\u0637', '\u0645', '\u064a']), ('\ufd75', &['\u0639', '\u062c', '\u0645']), ('\ufd76',
+ &['\u0639', '\u0645', '\u0645']), ('\ufd77', &['\u0639', '\u0645', '\u0645']), ('\ufd78',
+ &['\u0639', '\u0645', '\u0649']), ('\ufd79', &['\u063a', '\u0645', '\u0645']), ('\ufd7a',
+ &['\u063a', '\u0645', '\u064a']), ('\ufd7b', &['\u063a', '\u0645', '\u0649']), ('\ufd7c',
+ &['\u0641', '\u062e', '\u0645']), ('\ufd7d', &['\u0641', '\u062e', '\u0645']), ('\ufd7e',
+ &['\u0642', '\u0645', '\u062d']), ('\ufd7f', &['\u0642', '\u0645', '\u0645']), ('\ufd80',
+ &['\u0644', '\u062d', '\u0645']), ('\ufd81', &['\u0644', '\u062d', '\u064a']), ('\ufd82',
+ &['\u0644', '\u062d', '\u0649']), ('\ufd83', &['\u0644', '\u062c', '\u062c']), ('\ufd84',
+ &['\u0644', '\u062c', '\u062c']), ('\ufd85', &['\u0644', '\u062e', '\u0645']), ('\ufd86',
+ &['\u0644', '\u062e', '\u0645']), ('\ufd87', &['\u0644', '\u0645', '\u062d']), ('\ufd88',
+ &['\u0644', '\u0645', '\u062d']), ('\ufd89', &['\u0645', '\u062d', '\u062c']), ('\ufd8a',
+ &['\u0645', '\u062d', '\u0645']), ('\ufd8b', &['\u0645', '\u062d', '\u064a']), ('\ufd8c',
+ &['\u0645', '\u062c', '\u062d']), ('\ufd8d', &['\u0645', '\u062c', '\u0645']), ('\ufd8e',
+ &['\u0645', '\u062e', '\u062c']), ('\ufd8f', &['\u0645', '\u062e', '\u0645']), ('\ufd92',
+ &['\u0645', '\u062c', '\u062e']), ('\ufd93', &['\u0647', '\u0645', '\u062c']), ('\ufd94',
+ &['\u0647', '\u0645', '\u0645']), ('\ufd95', &['\u0646', '\u062d', '\u0645']), ('\ufd96',
+ &['\u0646', '\u062d', '\u0649']), ('\ufd97', &['\u0646', '\u062c', '\u0645']), ('\ufd98',
+ &['\u0646', '\u062c', '\u0645']), ('\ufd99', &['\u0646', '\u062c', '\u0649']), ('\ufd9a',
+ &['\u0646', '\u0645', '\u064a']), ('\ufd9b', &['\u0646', '\u0645', '\u0649']), ('\ufd9c',
+ &['\u064a', '\u0645', '\u0645']), ('\ufd9d', &['\u064a', '\u0645', '\u0645']), ('\ufd9e',
+ &['\u0628', '\u062e', '\u064a']), ('\ufd9f', &['\u062a', '\u062c', '\u064a']), ('\ufda0',
+ &['\u062a', '\u062c', '\u0649']), ('\ufda1', &['\u062a', '\u062e', '\u064a']), ('\ufda2',
+ &['\u062a', '\u062e', '\u0649']), ('\ufda3', &['\u062a', '\u0645', '\u064a']), ('\ufda4',
+ &['\u062a', '\u0645', '\u0649']), ('\ufda5', &['\u062c', '\u0645', '\u064a']), ('\ufda6',
+ &['\u062c', '\u062d', '\u0649']), ('\ufda7', &['\u062c', '\u0645', '\u0649']), ('\ufda8',
+ &['\u0633', '\u062e', '\u0649']), ('\ufda9', &['\u0635', '\u062d', '\u064a']), ('\ufdaa',
+ &['\u0634', '\u062d', '\u064a']), ('\ufdab', &['\u0636', '\u062d', '\u064a']), ('\ufdac',
+ &['\u0644', '\u062c', '\u064a']), ('\ufdad', &['\u0644', '\u0645', '\u064a']), ('\ufdae',
+ &['\u064a', '\u062d', '\u064a']), ('\ufdaf', &['\u064a', '\u062c', '\u064a']), ('\ufdb0',
+ &['\u064a', '\u0645', '\u064a']), ('\ufdb1', &['\u0645', '\u0645', '\u064a']), ('\ufdb2',
+ &['\u0642', '\u0645', '\u064a']), ('\ufdb3', &['\u0646', '\u062d', '\u064a']), ('\ufdb4',
+ &['\u0642', '\u0645', '\u062d']), ('\ufdb5', &['\u0644', '\u062d', '\u0645']), ('\ufdb6',
+ &['\u0639', '\u0645', '\u064a']), ('\ufdb7', &['\u0643', '\u0645', '\u064a']), ('\ufdb8',
+ &['\u0646', '\u062c', '\u062d']), ('\ufdb9', &['\u0645', '\u062e', '\u064a']), ('\ufdba',
+ &['\u0644', '\u062c', '\u0645']), ('\ufdbb', &['\u0643', '\u0645', '\u0645']), ('\ufdbc',
+ &['\u0644', '\u062c', '\u0645']), ('\ufdbd', &['\u0646', '\u062c', '\u062d']), ('\ufdbe',
+ &['\u062c', '\u062d', '\u064a']), ('\ufdbf', &['\u062d', '\u062c', '\u064a']), ('\ufdc0',
+ &['\u0645', '\u062c', '\u064a']), ('\ufdc1', &['\u0641', '\u0645', '\u064a']), ('\ufdc2',
+ &['\u0628', '\u062d', '\u064a']), ('\ufdc3', &['\u0643', '\u0645', '\u0645']), ('\ufdc4',
+ &['\u0639', '\u062c', '\u0645']), ('\ufdc5', &['\u0635', '\u0645', '\u0645']), ('\ufdc6',
+ &['\u0633', '\u062e', '\u064a']), ('\ufdc7', &['\u0646', '\u062c', '\u064a']), ('\ufdf0',
+ &['\u0635', '\u0644', '\u06d2']), ('\ufdf1', &['\u0642', '\u0644', '\u06d2']), ('\ufdf2',
+ &['\u0627', '\u0644', '\u0644', '\u0647']), ('\ufdf3', &['\u0627', '\u0643', '\u0628',
+ '\u0631']), ('\ufdf4', &['\u0645', '\u062d', '\u0645', '\u062f']), ('\ufdf5', &['\u0635',
+ '\u0644', '\u0639', '\u0645']), ('\ufdf6', &['\u0631', '\u0633', '\u0648', '\u0644']),
+ ('\ufdf7', &['\u0639', '\u0644', '\u064a', '\u0647']), ('\ufdf8', &['\u0648', '\u0633',
+ '\u0644', '\u0645']), ('\ufdf9', &['\u0635', '\u0644', '\u0649']), ('\ufdfa', &['\u0635',
+ '\u0644', '\u0649', '\x20', '\u0627', '\u0644', '\u0644', '\u0647', '\x20', '\u0639',
+ '\u0644', '\u064a', '\u0647', '\x20', '\u0648', '\u0633', '\u0644', '\u0645']), ('\ufdfb',
+ &['\u062c', '\u0644', '\x20', '\u062c', '\u0644', '\u0627', '\u0644', '\u0647']), ('\ufdfc',
+ &['\u0631', '\u06cc', '\u0627', '\u0644']), ('\ufe10', &['\x2c']), ('\ufe11', &['\u3001']),
+ ('\ufe12', &['\u3002']), ('\ufe13', &['\x3a']), ('\ufe14', &['\x3b']), ('\ufe15',
+ &['\x21']), ('\ufe16', &['\x3f']), ('\ufe17', &['\u3016']), ('\ufe18', &['\u3017']),
+ ('\ufe19', &['\u2026']), ('\ufe30', &['\u2025']), ('\ufe31', &['\u2014']), ('\ufe32',
+ &['\u2013']), ('\ufe33', &['\x5f']), ('\ufe34', &['\x5f']), ('\ufe35', &['\x28']),
+ ('\ufe36', &['\x29']), ('\ufe37', &['\x7b']), ('\ufe38', &['\x7d']), ('\ufe39',
+ &['\u3014']), ('\ufe3a', &['\u3015']), ('\ufe3b', &['\u3010']), ('\ufe3c', &['\u3011']),
+ ('\ufe3d', &['\u300a']), ('\ufe3e', &['\u300b']), ('\ufe3f', &['\u3008']), ('\ufe40',
+ &['\u3009']), ('\ufe41', &['\u300c']), ('\ufe42', &['\u300d']), ('\ufe43', &['\u300e']),
+ ('\ufe44', &['\u300f']), ('\ufe47', &['\x5b']), ('\ufe48', &['\x5d']), ('\ufe49',
+ &['\u203e']), ('\ufe4a', &['\u203e']), ('\ufe4b', &['\u203e']), ('\ufe4c', &['\u203e']),
+ ('\ufe4d', &['\x5f']), ('\ufe4e', &['\x5f']), ('\ufe4f', &['\x5f']), ('\ufe50', &['\x2c']),
+ ('\ufe51', &['\u3001']), ('\ufe52', &['\x2e']), ('\ufe54', &['\x3b']), ('\ufe55',
+ &['\x3a']), ('\ufe56', &['\x3f']), ('\ufe57', &['\x21']), ('\ufe58', &['\u2014']),
+ ('\ufe59', &['\x28']), ('\ufe5a', &['\x29']), ('\ufe5b', &['\x7b']), ('\ufe5c', &['\x7d']),
+ ('\ufe5d', &['\u3014']), ('\ufe5e', &['\u3015']), ('\ufe5f', &['\x23']), ('\ufe60',
+ &['\x26']), ('\ufe61', &['\x2a']), ('\ufe62', &['\x2b']), ('\ufe63', &['\x2d']), ('\ufe64',
+ &['\x3c']), ('\ufe65', &['\x3e']), ('\ufe66', &['\x3d']), ('\ufe68', &['\x5c']), ('\ufe69',
+ &['\x24']), ('\ufe6a', &['\x25']), ('\ufe6b', &['\x40']), ('\ufe70', &['\x20', '\u064b']),
+ ('\ufe71', &['\u0640', '\u064b']), ('\ufe72', &['\x20', '\u064c']), ('\ufe74', &['\x20',
+ '\u064d']), ('\ufe76', &['\x20', '\u064e']), ('\ufe77', &['\u0640', '\u064e']), ('\ufe78',
+ &['\x20', '\u064f']), ('\ufe79', &['\u0640', '\u064f']), ('\ufe7a', &['\x20', '\u0650']),
+ ('\ufe7b', &['\u0640', '\u0650']), ('\ufe7c', &['\x20', '\u0651']), ('\ufe7d', &['\u0640',
+ '\u0651']), ('\ufe7e', &['\x20', '\u0652']), ('\ufe7f', &['\u0640', '\u0652']), ('\ufe80',
+ &['\u0621']), ('\ufe81', &['\u0622']), ('\ufe82', &['\u0622']), ('\ufe83', &['\u0623']),
+ ('\ufe84', &['\u0623']), ('\ufe85', &['\u0624']), ('\ufe86', &['\u0624']), ('\ufe87',
+ &['\u0625']), ('\ufe88', &['\u0625']), ('\ufe89', &['\u0626']), ('\ufe8a', &['\u0626']),
+ ('\ufe8b', &['\u0626']), ('\ufe8c', &['\u0626']), ('\ufe8d', &['\u0627']), ('\ufe8e',
+ &['\u0627']), ('\ufe8f', &['\u0628']), ('\ufe90', &['\u0628']), ('\ufe91', &['\u0628']),
+ ('\ufe92', &['\u0628']), ('\ufe93', &['\u0629']), ('\ufe94', &['\u0629']), ('\ufe95',
+ &['\u062a']), ('\ufe96', &['\u062a']), ('\ufe97', &['\u062a']), ('\ufe98', &['\u062a']),
+ ('\ufe99', &['\u062b']), ('\ufe9a', &['\u062b']), ('\ufe9b', &['\u062b']), ('\ufe9c',
+ &['\u062b']), ('\ufe9d', &['\u062c']), ('\ufe9e', &['\u062c']), ('\ufe9f', &['\u062c']),
+ ('\ufea0', &['\u062c']), ('\ufea1', &['\u062d']), ('\ufea2', &['\u062d']), ('\ufea3',
+ &['\u062d']), ('\ufea4', &['\u062d']), ('\ufea5', &['\u062e']), ('\ufea6', &['\u062e']),
+ ('\ufea7', &['\u062e']), ('\ufea8', &['\u062e']), ('\ufea9', &['\u062f']), ('\ufeaa',
+ &['\u062f']), ('\ufeab', &['\u0630']), ('\ufeac', &['\u0630']), ('\ufead', &['\u0631']),
+ ('\ufeae', &['\u0631']), ('\ufeaf', &['\u0632']), ('\ufeb0', &['\u0632']), ('\ufeb1',
+ &['\u0633']), ('\ufeb2', &['\u0633']), ('\ufeb3', &['\u0633']), ('\ufeb4', &['\u0633']),
+ ('\ufeb5', &['\u0634']), ('\ufeb6', &['\u0634']), ('\ufeb7', &['\u0634']), ('\ufeb8',
+ &['\u0634']), ('\ufeb9', &['\u0635']), ('\ufeba', &['\u0635']), ('\ufebb', &['\u0635']),
+ ('\ufebc', &['\u0635']), ('\ufebd', &['\u0636']), ('\ufebe', &['\u0636']), ('\ufebf',
+ &['\u0636']), ('\ufec0', &['\u0636']), ('\ufec1', &['\u0637']), ('\ufec2', &['\u0637']),
+ ('\ufec3', &['\u0637']), ('\ufec4', &['\u0637']), ('\ufec5', &['\u0638']), ('\ufec6',
+ &['\u0638']), ('\ufec7', &['\u0638']), ('\ufec8', &['\u0638']), ('\ufec9', &['\u0639']),
+ ('\ufeca', &['\u0639']), ('\ufecb', &['\u0639']), ('\ufecc', &['\u0639']), ('\ufecd',
+ &['\u063a']), ('\ufece', &['\u063a']), ('\ufecf', &['\u063a']), ('\ufed0', &['\u063a']),
+ ('\ufed1', &['\u0641']), ('\ufed2', &['\u0641']), ('\ufed3', &['\u0641']), ('\ufed4',
+ &['\u0641']), ('\ufed5', &['\u0642']), ('\ufed6', &['\u0642']), ('\ufed7', &['\u0642']),
+ ('\ufed8', &['\u0642']), ('\ufed9', &['\u0643']), ('\ufeda', &['\u0643']), ('\ufedb',
+ &['\u0643']), ('\ufedc', &['\u0643']), ('\ufedd', &['\u0644']), ('\ufede', &['\u0644']),
+ ('\ufedf', &['\u0644']), ('\ufee0', &['\u0644']), ('\ufee1', &['\u0645']), ('\ufee2',
+ &['\u0645']), ('\ufee3', &['\u0645']), ('\ufee4', &['\u0645']), ('\ufee5', &['\u0646']),
+ ('\ufee6', &['\u0646']), ('\ufee7', &['\u0646']), ('\ufee8', &['\u0646']), ('\ufee9',
+ &['\u0647']), ('\ufeea', &['\u0647']), ('\ufeeb', &['\u0647']), ('\ufeec', &['\u0647']),
+ ('\ufeed', &['\u0648']), ('\ufeee', &['\u0648']), ('\ufeef', &['\u0649']), ('\ufef0',
+ &['\u0649']), ('\ufef1', &['\u064a']), ('\ufef2', &['\u064a']), ('\ufef3', &['\u064a']),
+ ('\ufef4', &['\u064a']), ('\ufef5', &['\u0644', '\u0622']), ('\ufef6', &['\u0644',
+ '\u0622']), ('\ufef7', &['\u0644', '\u0623']), ('\ufef8', &['\u0644', '\u0623']), ('\ufef9',
+ &['\u0644', '\u0625']), ('\ufefa', &['\u0644', '\u0625']), ('\ufefb', &['\u0644',
+ '\u0627']), ('\ufefc', &['\u0644', '\u0627']), ('\uff01', &['\x21']), ('\uff02', &['\x22']),
+ ('\uff03', &['\x23']), ('\uff04', &['\x24']), ('\uff05', &['\x25']), ('\uff06', &['\x26']),
+ ('\uff07', &['\x27']), ('\uff08', &['\x28']), ('\uff09', &['\x29']), ('\uff0a', &['\x2a']),
+ ('\uff0b', &['\x2b']), ('\uff0c', &['\x2c']), ('\uff0d', &['\x2d']), ('\uff0e', &['\x2e']),
+ ('\uff0f', &['\x2f']), ('\uff10', &['\x30']), ('\uff11', &['\x31']), ('\uff12', &['\x32']),
+ ('\uff13', &['\x33']), ('\uff14', &['\x34']), ('\uff15', &['\x35']), ('\uff16', &['\x36']),
+ ('\uff17', &['\x37']), ('\uff18', &['\x38']), ('\uff19', &['\x39']), ('\uff1a', &['\x3a']),
+ ('\uff1b', &['\x3b']), ('\uff1c', &['\x3c']), ('\uff1d', &['\x3d']), ('\uff1e', &['\x3e']),
+ ('\uff1f', &['\x3f']), ('\uff20', &['\x40']), ('\uff21', &['\x41']), ('\uff22', &['\x42']),
+ ('\uff23', &['\x43']), ('\uff24', &['\x44']), ('\uff25', &['\x45']), ('\uff26', &['\x46']),
+ ('\uff27', &['\x47']), ('\uff28', &['\x48']), ('\uff29', &['\x49']), ('\uff2a', &['\x4a']),
+ ('\uff2b', &['\x4b']), ('\uff2c', &['\x4c']), ('\uff2d', &['\x4d']), ('\uff2e', &['\x4e']),
+ ('\uff2f', &['\x4f']), ('\uff30', &['\x50']), ('\uff31', &['\x51']), ('\uff32', &['\x52']),
+ ('\uff33', &['\x53']), ('\uff34', &['\x54']), ('\uff35', &['\x55']), ('\uff36', &['\x56']),
+ ('\uff37', &['\x57']), ('\uff38', &['\x58']), ('\uff39', &['\x59']), ('\uff3a', &['\x5a']),
+ ('\uff3b', &['\x5b']), ('\uff3c', &['\x5c']), ('\uff3d', &['\x5d']), ('\uff3e', &['\x5e']),
+ ('\uff3f', &['\x5f']), ('\uff40', &['\x60']), ('\uff41', &['\x61']), ('\uff42', &['\x62']),
+ ('\uff43', &['\x63']), ('\uff44', &['\x64']), ('\uff45', &['\x65']), ('\uff46', &['\x66']),
+ ('\uff47', &['\x67']), ('\uff48', &['\x68']), ('\uff49', &['\x69']), ('\uff4a', &['\x6a']),
+ ('\uff4b', &['\x6b']), ('\uff4c', &['\x6c']), ('\uff4d', &['\x6d']), ('\uff4e', &['\x6e']),
+ ('\uff4f', &['\x6f']), ('\uff50', &['\x70']), ('\uff51', &['\x71']), ('\uff52', &['\x72']),
+ ('\uff53', &['\x73']), ('\uff54', &['\x74']), ('\uff55', &['\x75']), ('\uff56', &['\x76']),
+ ('\uff57', &['\x77']), ('\uff58', &['\x78']), ('\uff59', &['\x79']), ('\uff5a', &['\x7a']),
+ ('\uff5b', &['\x7b']), ('\uff5c', &['\x7c']), ('\uff5d', &['\x7d']), ('\uff5e', &['\x7e']),
+ ('\uff5f', &['\u2985']), ('\uff60', &['\u2986']), ('\uff61', &['\u3002']), ('\uff62',
+ &['\u300c']), ('\uff63', &['\u300d']), ('\uff64', &['\u3001']), ('\uff65', &['\u30fb']),
+ ('\uff66', &['\u30f2']), ('\uff67', &['\u30a1']), ('\uff68', &['\u30a3']), ('\uff69',
+ &['\u30a5']), ('\uff6a', &['\u30a7']), ('\uff6b', &['\u30a9']), ('\uff6c', &['\u30e3']),
+ ('\uff6d', &['\u30e5']), ('\uff6e', &['\u30e7']), ('\uff6f', &['\u30c3']), ('\uff70',
+ &['\u30fc']), ('\uff71', &['\u30a2']), ('\uff72', &['\u30a4']), ('\uff73', &['\u30a6']),
+ ('\uff74', &['\u30a8']), ('\uff75', &['\u30aa']), ('\uff76', &['\u30ab']), ('\uff77',
+ &['\u30ad']), ('\uff78', &['\u30af']), ('\uff79', &['\u30b1']), ('\uff7a', &['\u30b3']),
+ ('\uff7b', &['\u30b5']), ('\uff7c', &['\u30b7']), ('\uff7d', &['\u30b9']), ('\uff7e',
+ &['\u30bb']), ('\uff7f', &['\u30bd']), ('\uff80', &['\u30bf']), ('\uff81', &['\u30c1']),
+ ('\uff82', &['\u30c4']), ('\uff83', &['\u30c6']), ('\uff84', &['\u30c8']), ('\uff85',
+ &['\u30ca']), ('\uff86', &['\u30cb']), ('\uff87', &['\u30cc']), ('\uff88', &['\u30cd']),
+ ('\uff89', &['\u30ce']), ('\uff8a', &['\u30cf']), ('\uff8b', &['\u30d2']), ('\uff8c',
+ &['\u30d5']), ('\uff8d', &['\u30d8']), ('\uff8e', &['\u30db']), ('\uff8f', &['\u30de']),
+ ('\uff90', &['\u30df']), ('\uff91', &['\u30e0']), ('\uff92', &['\u30e1']), ('\uff93',
+ &['\u30e2']), ('\uff94', &['\u30e4']), ('\uff95', &['\u30e6']), ('\uff96', &['\u30e8']),
+ ('\uff97', &['\u30e9']), ('\uff98', &['\u30ea']), ('\uff99', &['\u30eb']), ('\uff9a',
+ &['\u30ec']), ('\uff9b', &['\u30ed']), ('\uff9c', &['\u30ef']), ('\uff9d', &['\u30f3']),
+ ('\uff9e', &['\u3099']), ('\uff9f', &['\u309a']), ('\uffa0', &['\u3164']), ('\uffa1',
+ &['\u3131']), ('\uffa2', &['\u3132']), ('\uffa3', &['\u3133']), ('\uffa4', &['\u3134']),
+ ('\uffa5', &['\u3135']), ('\uffa6', &['\u3136']), ('\uffa7', &['\u3137']), ('\uffa8',
+ &['\u3138']), ('\uffa9', &['\u3139']), ('\uffaa', &['\u313a']), ('\uffab', &['\u313b']),
+ ('\uffac', &['\u313c']), ('\uffad', &['\u313d']), ('\uffae', &['\u313e']), ('\uffaf',
+ &['\u313f']), ('\uffb0', &['\u3140']), ('\uffb1', &['\u3141']), ('\uffb2', &['\u3142']),
+ ('\uffb3', &['\u3143']), ('\uffb4', &['\u3144']), ('\uffb5', &['\u3145']), ('\uffb6',
+ &['\u3146']), ('\uffb7', &['\u3147']), ('\uffb8', &['\u3148']), ('\uffb9', &['\u3149']),
+ ('\uffba', &['\u314a']), ('\uffbb', &['\u314b']), ('\uffbc', &['\u314c']), ('\uffbd',
+ &['\u314d']), ('\uffbe', &['\u314e']), ('\uffc2', &['\u314f']), ('\uffc3', &['\u3150']),
+ ('\uffc4', &['\u3151']), ('\uffc5', &['\u3152']), ('\uffc6', &['\u3153']), ('\uffc7',
+ &['\u3154']), ('\uffca', &['\u3155']), ('\uffcb', &['\u3156']), ('\uffcc', &['\u3157']),
+ ('\uffcd', &['\u3158']), ('\uffce', &['\u3159']), ('\uffcf', &['\u315a']), ('\uffd2',
+ &['\u315b']), ('\uffd3', &['\u315c']), ('\uffd4', &['\u315d']), ('\uffd5', &['\u315e']),
+ ('\uffd6', &['\u315f']), ('\uffd7', &['\u3160']), ('\uffda', &['\u3161']), ('\uffdb',
+ &['\u3162']), ('\uffdc', &['\u3163']), ('\uffe0', &['\xa2']), ('\uffe1', &['\xa3']),
+ ('\uffe2', &['\xac']), ('\uffe3', &['\xaf']), ('\uffe4', &['\xa6']), ('\uffe5', &['\xa5']),
+ ('\uffe6', &['\u20a9']), ('\uffe8', &['\u2502']), ('\uffe9', &['\u2190']), ('\uffea',
+ &['\u2191']), ('\uffeb', &['\u2192']), ('\uffec', &['\u2193']), ('\uffed', &['\u25a0']),
+ ('\uffee', &['\u25cb']), ('\U0001d400', &['\x41']), ('\U0001d401', &['\x42']),
+ ('\U0001d402', &['\x43']), ('\U0001d403', &['\x44']), ('\U0001d404', &['\x45']),
+ ('\U0001d405', &['\x46']), ('\U0001d406', &['\x47']), ('\U0001d407', &['\x48']),
+ ('\U0001d408', &['\x49']), ('\U0001d409', &['\x4a']), ('\U0001d40a', &['\x4b']),
+ ('\U0001d40b', &['\x4c']), ('\U0001d40c', &['\x4d']), ('\U0001d40d', &['\x4e']),
+ ('\U0001d40e', &['\x4f']), ('\U0001d40f', &['\x50']), ('\U0001d410', &['\x51']),
+ ('\U0001d411', &['\x52']), ('\U0001d412', &['\x53']), ('\U0001d413', &['\x54']),
+ ('\U0001d414', &['\x55']), ('\U0001d415', &['\x56']), ('\U0001d416', &['\x57']),
+ ('\U0001d417', &['\x58']), ('\U0001d418', &['\x59']), ('\U0001d419', &['\x5a']),
+ ('\U0001d41a', &['\x61']), ('\U0001d41b', &['\x62']), ('\U0001d41c', &['\x63']),
+ ('\U0001d41d', &['\x64']), ('\U0001d41e', &['\x65']), ('\U0001d41f', &['\x66']),
+ ('\U0001d420', &['\x67']), ('\U0001d421', &['\x68']), ('\U0001d422', &['\x69']),
+ ('\U0001d423', &['\x6a']), ('\U0001d424', &['\x6b']), ('\U0001d425', &['\x6c']),
+ ('\U0001d426', &['\x6d']), ('\U0001d427', &['\x6e']), ('\U0001d428', &['\x6f']),
+ ('\U0001d429', &['\x70']), ('\U0001d42a', &['\x71']), ('\U0001d42b', &['\x72']),
+ ('\U0001d42c', &['\x73']), ('\U0001d42d', &['\x74']), ('\U0001d42e', &['\x75']),
+ ('\U0001d42f', &['\x76']), ('\U0001d430', &['\x77']), ('\U0001d431', &['\x78']),
+ ('\U0001d432', &['\x79']), ('\U0001d433', &['\x7a']), ('\U0001d434', &['\x41']),
+ ('\U0001d435', &['\x42']), ('\U0001d436', &['\x43']), ('\U0001d437', &['\x44']),
+ ('\U0001d438', &['\x45']), ('\U0001d439', &['\x46']), ('\U0001d43a', &['\x47']),
+ ('\U0001d43b', &['\x48']), ('\U0001d43c', &['\x49']), ('\U0001d43d', &['\x4a']),
+ ('\U0001d43e', &['\x4b']), ('\U0001d43f', &['\x4c']), ('\U0001d440', &['\x4d']),
+ ('\U0001d441', &['\x4e']), ('\U0001d442', &['\x4f']), ('\U0001d443', &['\x50']),
+ ('\U0001d444', &['\x51']), ('\U0001d445', &['\x52']), ('\U0001d446', &['\x53']),
+ ('\U0001d447', &['\x54']), ('\U0001d448', &['\x55']), ('\U0001d449', &['\x56']),
+ ('\U0001d44a', &['\x57']), ('\U0001d44b', &['\x58']), ('\U0001d44c', &['\x59']),
+ ('\U0001d44d', &['\x5a']), ('\U0001d44e', &['\x61']), ('\U0001d44f', &['\x62']),
+ ('\U0001d450', &['\x63']), ('\U0001d451', &['\x64']), ('\U0001d452', &['\x65']),
+ ('\U0001d453', &['\x66']), ('\U0001d454', &['\x67']), ('\U0001d456', &['\x69']),
+ ('\U0001d457', &['\x6a']), ('\U0001d458', &['\x6b']), ('\U0001d459', &['\x6c']),
+ ('\U0001d45a', &['\x6d']), ('\U0001d45b', &['\x6e']), ('\U0001d45c', &['\x6f']),
+ ('\U0001d45d', &['\x70']), ('\U0001d45e', &['\x71']), ('\U0001d45f', &['\x72']),
+ ('\U0001d460', &['\x73']), ('\U0001d461', &['\x74']), ('\U0001d462', &['\x75']),
+ ('\U0001d463', &['\x76']), ('\U0001d464', &['\x77']), ('\U0001d465', &['\x78']),
+ ('\U0001d466', &['\x79']), ('\U0001d467', &['\x7a']), ('\U0001d468', &['\x41']),
+ ('\U0001d469', &['\x42']), ('\U0001d46a', &['\x43']), ('\U0001d46b', &['\x44']),
+ ('\U0001d46c', &['\x45']), ('\U0001d46d', &['\x46']), ('\U0001d46e', &['\x47']),
+ ('\U0001d46f', &['\x48']), ('\U0001d470', &['\x49']), ('\U0001d471', &['\x4a']),
+ ('\U0001d472', &['\x4b']), ('\U0001d473', &['\x4c']), ('\U0001d474', &['\x4d']),
+ ('\U0001d475', &['\x4e']), ('\U0001d476', &['\x4f']), ('\U0001d477', &['\x50']),
+ ('\U0001d478', &['\x51']), ('\U0001d479', &['\x52']), ('\U0001d47a', &['\x53']),
+ ('\U0001d47b', &['\x54']), ('\U0001d47c', &['\x55']), ('\U0001d47d', &['\x56']),
+ ('\U0001d47e', &['\x57']), ('\U0001d47f', &['\x58']), ('\U0001d480', &['\x59']),
+ ('\U0001d481', &['\x5a']), ('\U0001d482', &['\x61']), ('\U0001d483', &['\x62']),
+ ('\U0001d484', &['\x63']), ('\U0001d485', &['\x64']), ('\U0001d486', &['\x65']),
+ ('\U0001d487', &['\x66']), ('\U0001d488', &['\x67']), ('\U0001d489', &['\x68']),
+ ('\U0001d48a', &['\x69']), ('\U0001d48b', &['\x6a']), ('\U0001d48c', &['\x6b']),
+ ('\U0001d48d', &['\x6c']), ('\U0001d48e', &['\x6d']), ('\U0001d48f', &['\x6e']),
+ ('\U0001d490', &['\x6f']), ('\U0001d491', &['\x70']), ('\U0001d492', &['\x71']),
+ ('\U0001d493', &['\x72']), ('\U0001d494', &['\x73']), ('\U0001d495', &['\x74']),
+ ('\U0001d496', &['\x75']), ('\U0001d497', &['\x76']), ('\U0001d498', &['\x77']),
+ ('\U0001d499', &['\x78']), ('\U0001d49a', &['\x79']), ('\U0001d49b', &['\x7a']),
+ ('\U0001d49c', &['\x41']), ('\U0001d49e', &['\x43']), ('\U0001d49f', &['\x44']),
+ ('\U0001d4a2', &['\x47']), ('\U0001d4a5', &['\x4a']), ('\U0001d4a6', &['\x4b']),
+ ('\U0001d4a9', &['\x4e']), ('\U0001d4aa', &['\x4f']), ('\U0001d4ab', &['\x50']),
+ ('\U0001d4ac', &['\x51']), ('\U0001d4ae', &['\x53']), ('\U0001d4af', &['\x54']),
+ ('\U0001d4b0', &['\x55']), ('\U0001d4b1', &['\x56']), ('\U0001d4b2', &['\x57']),
+ ('\U0001d4b3', &['\x58']), ('\U0001d4b4', &['\x59']), ('\U0001d4b5', &['\x5a']),
+ ('\U0001d4b6', &['\x61']), ('\U0001d4b7', &['\x62']), ('\U0001d4b8', &['\x63']),
+ ('\U0001d4b9', &['\x64']), ('\U0001d4bb', &['\x66']), ('\U0001d4bd', &['\x68']),
+ ('\U0001d4be', &['\x69']), ('\U0001d4bf', &['\x6a']), ('\U0001d4c0', &['\x6b']),
+ ('\U0001d4c1', &['\x6c']), ('\U0001d4c2', &['\x6d']), ('\U0001d4c3', &['\x6e']),
+ ('\U0001d4c5', &['\x70']), ('\U0001d4c6', &['\x71']), ('\U0001d4c7', &['\x72']),
+ ('\U0001d4c8', &['\x73']), ('\U0001d4c9', &['\x74']), ('\U0001d4ca', &['\x75']),
+ ('\U0001d4cb', &['\x76']), ('\U0001d4cc', &['\x77']), ('\U0001d4cd', &['\x78']),
+ ('\U0001d4ce', &['\x79']), ('\U0001d4cf', &['\x7a']), ('\U0001d4d0', &['\x41']),
+ ('\U0001d4d1', &['\x42']), ('\U0001d4d2', &['\x43']), ('\U0001d4d3', &['\x44']),
+ ('\U0001d4d4', &['\x45']), ('\U0001d4d5', &['\x46']), ('\U0001d4d6', &['\x47']),
+ ('\U0001d4d7', &['\x48']), ('\U0001d4d8', &['\x49']), ('\U0001d4d9', &['\x4a']),
+ ('\U0001d4da', &['\x4b']), ('\U0001d4db', &['\x4c']), ('\U0001d4dc', &['\x4d']),
+ ('\U0001d4dd', &['\x4e']), ('\U0001d4de', &['\x4f']), ('\U0001d4df', &['\x50']),
+ ('\U0001d4e0', &['\x51']), ('\U0001d4e1', &['\x52']), ('\U0001d4e2', &['\x53']),
+ ('\U0001d4e3', &['\x54']), ('\U0001d4e4', &['\x55']), ('\U0001d4e5', &['\x56']),
+ ('\U0001d4e6', &['\x57']), ('\U0001d4e7', &['\x58']), ('\U0001d4e8', &['\x59']),
+ ('\U0001d4e9', &['\x5a']), ('\U0001d4ea', &['\x61']), ('\U0001d4eb', &['\x62']),
+ ('\U0001d4ec', &['\x63']), ('\U0001d4ed', &['\x64']), ('\U0001d4ee', &['\x65']),
+ ('\U0001d4ef', &['\x66']), ('\U0001d4f0', &['\x67']), ('\U0001d4f1', &['\x68']),
+ ('\U0001d4f2', &['\x69']), ('\U0001d4f3', &['\x6a']), ('\U0001d4f4', &['\x6b']),
+ ('\U0001d4f5', &['\x6c']), ('\U0001d4f6', &['\x6d']), ('\U0001d4f7', &['\x6e']),
+ ('\U0001d4f8', &['\x6f']), ('\U0001d4f9', &['\x70']), ('\U0001d4fa', &['\x71']),
+ ('\U0001d4fb', &['\x72']), ('\U0001d4fc', &['\x73']), ('\U0001d4fd', &['\x74']),
+ ('\U0001d4fe', &['\x75']), ('\U0001d4ff', &['\x76']), ('\U0001d500', &['\x77']),
+ ('\U0001d501', &['\x78']), ('\U0001d502', &['\x79']), ('\U0001d503', &['\x7a']),
+ ('\U0001d504', &['\x41']), ('\U0001d505', &['\x42']), ('\U0001d507', &['\x44']),
+ ('\U0001d508', &['\x45']), ('\U0001d509', &['\x46']), ('\U0001d50a', &['\x47']),
+ ('\U0001d50d', &['\x4a']), ('\U0001d50e', &['\x4b']), ('\U0001d50f', &['\x4c']),
+ ('\U0001d510', &['\x4d']), ('\U0001d511', &['\x4e']), ('\U0001d512', &['\x4f']),
+ ('\U0001d513', &['\x50']), ('\U0001d514', &['\x51']), ('\U0001d516', &['\x53']),
+ ('\U0001d517', &['\x54']), ('\U0001d518', &['\x55']), ('\U0001d519', &['\x56']),
+ ('\U0001d51a', &['\x57']), ('\U0001d51b', &['\x58']), ('\U0001d51c', &['\x59']),
+ ('\U0001d51e', &['\x61']), ('\U0001d51f', &['\x62']), ('\U0001d520', &['\x63']),
+ ('\U0001d521', &['\x64']), ('\U0001d522', &['\x65']), ('\U0001d523', &['\x66']),
+ ('\U0001d524', &['\x67']), ('\U0001d525', &['\x68']), ('\U0001d526', &['\x69']),
+ ('\U0001d527', &['\x6a']), ('\U0001d528', &['\x6b']), ('\U0001d529', &['\x6c']),
+ ('\U0001d52a', &['\x6d']), ('\U0001d52b', &['\x6e']), ('\U0001d52c', &['\x6f']),
+ ('\U0001d52d', &['\x70']), ('\U0001d52e', &['\x71']), ('\U0001d52f', &['\x72']),
+ ('\U0001d530', &['\x73']), ('\U0001d531', &['\x74']), ('\U0001d532', &['\x75']),
+ ('\U0001d533', &['\x76']), ('\U0001d534', &['\x77']), ('\U0001d535', &['\x78']),
+ ('\U0001d536', &['\x79']), ('\U0001d537', &['\x7a']), ('\U0001d538', &['\x41']),
+ ('\U0001d539', &['\x42']), ('\U0001d53b', &['\x44']), ('\U0001d53c', &['\x45']),
+ ('\U0001d53d', &['\x46']), ('\U0001d53e', &['\x47']), ('\U0001d540', &['\x49']),
+ ('\U0001d541', &['\x4a']), ('\U0001d542', &['\x4b']), ('\U0001d543', &['\x4c']),
+ ('\U0001d544', &['\x4d']), ('\U0001d546', &['\x4f']), ('\U0001d54a', &['\x53']),
+ ('\U0001d54b', &['\x54']), ('\U0001d54c', &['\x55']), ('\U0001d54d', &['\x56']),
+ ('\U0001d54e', &['\x57']), ('\U0001d54f', &['\x58']), ('\U0001d550', &['\x59']),
+ ('\U0001d552', &['\x61']), ('\U0001d553', &['\x62']), ('\U0001d554', &['\x63']),
+ ('\U0001d555', &['\x64']), ('\U0001d556', &['\x65']), ('\U0001d557', &['\x66']),
+ ('\U0001d558', &['\x67']), ('\U0001d559', &['\x68']), ('\U0001d55a', &['\x69']),
+ ('\U0001d55b', &['\x6a']), ('\U0001d55c', &['\x6b']), ('\U0001d55d', &['\x6c']),
+ ('\U0001d55e', &['\x6d']), ('\U0001d55f', &['\x6e']), ('\U0001d560', &['\x6f']),
+ ('\U0001d561', &['\x70']), ('\U0001d562', &['\x71']), ('\U0001d563', &['\x72']),
+ ('\U0001d564', &['\x73']), ('\U0001d565', &['\x74']), ('\U0001d566', &['\x75']),
+ ('\U0001d567', &['\x76']), ('\U0001d568', &['\x77']), ('\U0001d569', &['\x78']),
+ ('\U0001d56a', &['\x79']), ('\U0001d56b', &['\x7a']), ('\U0001d56c', &['\x41']),
+ ('\U0001d56d', &['\x42']), ('\U0001d56e', &['\x43']), ('\U0001d56f', &['\x44']),
+ ('\U0001d570', &['\x45']), ('\U0001d571', &['\x46']), ('\U0001d572', &['\x47']),
+ ('\U0001d573', &['\x48']), ('\U0001d574', &['\x49']), ('\U0001d575', &['\x4a']),
+ ('\U0001d576', &['\x4b']), ('\U0001d577', &['\x4c']), ('\U0001d578', &['\x4d']),
+ ('\U0001d579', &['\x4e']), ('\U0001d57a', &['\x4f']), ('\U0001d57b', &['\x50']),
+ ('\U0001d57c', &['\x51']), ('\U0001d57d', &['\x52']), ('\U0001d57e', &['\x53']),
+ ('\U0001d57f', &['\x54']), ('\U0001d580', &['\x55']), ('\U0001d581', &['\x56']),
+ ('\U0001d582', &['\x57']), ('\U0001d583', &['\x58']), ('\U0001d584', &['\x59']),
+ ('\U0001d585', &['\x5a']), ('\U0001d586', &['\x61']), ('\U0001d587', &['\x62']),
+ ('\U0001d588', &['\x63']), ('\U0001d589', &['\x64']), ('\U0001d58a', &['\x65']),
+ ('\U0001d58b', &['\x66']), ('\U0001d58c', &['\x67']), ('\U0001d58d', &['\x68']),
+ ('\U0001d58e', &['\x69']), ('\U0001d58f', &['\x6a']), ('\U0001d590', &['\x6b']),
+ ('\U0001d591', &['\x6c']), ('\U0001d592', &['\x6d']), ('\U0001d593', &['\x6e']),
+ ('\U0001d594', &['\x6f']), ('\U0001d595', &['\x70']), ('\U0001d596', &['\x71']),
+ ('\U0001d597', &['\x72']), ('\U0001d598', &['\x73']), ('\U0001d599', &['\x74']),
+ ('\U0001d59a', &['\x75']), ('\U0001d59b', &['\x76']), ('\U0001d59c', &['\x77']),
+ ('\U0001d59d', &['\x78']), ('\U0001d59e', &['\x79']), ('\U0001d59f', &['\x7a']),
+ ('\U0001d5a0', &['\x41']), ('\U0001d5a1', &['\x42']), ('\U0001d5a2', &['\x43']),
+ ('\U0001d5a3', &['\x44']), ('\U0001d5a4', &['\x45']), ('\U0001d5a5', &['\x46']),
+ ('\U0001d5a6', &['\x47']), ('\U0001d5a7', &['\x48']), ('\U0001d5a8', &['\x49']),
+ ('\U0001d5a9', &['\x4a']), ('\U0001d5aa', &['\x4b']), ('\U0001d5ab', &['\x4c']),
+ ('\U0001d5ac', &['\x4d']), ('\U0001d5ad', &['\x4e']), ('\U0001d5ae', &['\x4f']),
+ ('\U0001d5af', &['\x50']), ('\U0001d5b0', &['\x51']), ('\U0001d5b1', &['\x52']),
+ ('\U0001d5b2', &['\x53']), ('\U0001d5b3', &['\x54']), ('\U0001d5b4', &['\x55']),
+ ('\U0001d5b5', &['\x56']), ('\U0001d5b6', &['\x57']), ('\U0001d5b7', &['\x58']),
+ ('\U0001d5b8', &['\x59']), ('\U0001d5b9', &['\x5a']), ('\U0001d5ba', &['\x61']),
+ ('\U0001d5bb', &['\x62']), ('\U0001d5bc', &['\x63']), ('\U0001d5bd', &['\x64']),
+ ('\U0001d5be', &['\x65']), ('\U0001d5bf', &['\x66']), ('\U0001d5c0', &['\x67']),
+ ('\U0001d5c1', &['\x68']), ('\U0001d5c2', &['\x69']), ('\U0001d5c3', &['\x6a']),
+ ('\U0001d5c4', &['\x6b']), ('\U0001d5c5', &['\x6c']), ('\U0001d5c6', &['\x6d']),
+ ('\U0001d5c7', &['\x6e']), ('\U0001d5c8', &['\x6f']), ('\U0001d5c9', &['\x70']),
+ ('\U0001d5ca', &['\x71']), ('\U0001d5cb', &['\x72']), ('\U0001d5cc', &['\x73']),
+ ('\U0001d5cd', &['\x74']), ('\U0001d5ce', &['\x75']), ('\U0001d5cf', &['\x76']),
+ ('\U0001d5d0', &['\x77']), ('\U0001d5d1', &['\x78']), ('\U0001d5d2', &['\x79']),
+ ('\U0001d5d3', &['\x7a']), ('\U0001d5d4', &['\x41']), ('\U0001d5d5', &['\x42']),
+ ('\U0001d5d6', &['\x43']), ('\U0001d5d7', &['\x44']), ('\U0001d5d8', &['\x45']),
+ ('\U0001d5d9', &['\x46']), ('\U0001d5da', &['\x47']), ('\U0001d5db', &['\x48']),
+ ('\U0001d5dc', &['\x49']), ('\U0001d5dd', &['\x4a']), ('\U0001d5de', &['\x4b']),
+ ('\U0001d5df', &['\x4c']), ('\U0001d5e0', &['\x4d']), ('\U0001d5e1', &['\x4e']),
+ ('\U0001d5e2', &['\x4f']), ('\U0001d5e3', &['\x50']), ('\U0001d5e4', &['\x51']),
+ ('\U0001d5e5', &['\x52']), ('\U0001d5e6', &['\x53']), ('\U0001d5e7', &['\x54']),
+ ('\U0001d5e8', &['\x55']), ('\U0001d5e9', &['\x56']), ('\U0001d5ea', &['\x57']),
+ ('\U0001d5eb', &['\x58']), ('\U0001d5ec', &['\x59']), ('\U0001d5ed', &['\x5a']),
+ ('\U0001d5ee', &['\x61']), ('\U0001d5ef', &['\x62']), ('\U0001d5f0', &['\x63']),
+ ('\U0001d5f1', &['\x64']), ('\U0001d5f2', &['\x65']), ('\U0001d5f3', &['\x66']),
+ ('\U0001d5f4', &['\x67']), ('\U0001d5f5', &['\x68']), ('\U0001d5f6', &['\x69']),
+ ('\U0001d5f7', &['\x6a']), ('\U0001d5f8', &['\x6b']), ('\U0001d5f9', &['\x6c']),
+ ('\U0001d5fa', &['\x6d']), ('\U0001d5fb', &['\x6e']), ('\U0001d5fc', &['\x6f']),
+ ('\U0001d5fd', &['\x70']), ('\U0001d5fe', &['\x71']), ('\U0001d5ff', &['\x72']),
+ ('\U0001d600', &['\x73']), ('\U0001d601', &['\x74']), ('\U0001d602', &['\x75']),
+ ('\U0001d603', &['\x76']), ('\U0001d604', &['\x77']), ('\U0001d605', &['\x78']),
+ ('\U0001d606', &['\x79']), ('\U0001d607', &['\x7a']), ('\U0001d608', &['\x41']),
+ ('\U0001d609', &['\x42']), ('\U0001d60a', &['\x43']), ('\U0001d60b', &['\x44']),
+ ('\U0001d60c', &['\x45']), ('\U0001d60d', &['\x46']), ('\U0001d60e', &['\x47']),
+ ('\U0001d60f', &['\x48']), ('\U0001d610', &['\x49']), ('\U0001d611', &['\x4a']),
+ ('\U0001d612', &['\x4b']), ('\U0001d613', &['\x4c']), ('\U0001d614', &['\x4d']),
+ ('\U0001d615', &['\x4e']), ('\U0001d616', &['\x4f']), ('\U0001d617', &['\x50']),
+ ('\U0001d618', &['\x51']), ('\U0001d619', &['\x52']), ('\U0001d61a', &['\x53']),
+ ('\U0001d61b', &['\x54']), ('\U0001d61c', &['\x55']), ('\U0001d61d', &['\x56']),
+ ('\U0001d61e', &['\x57']), ('\U0001d61f', &['\x58']), ('\U0001d620', &['\x59']),
+ ('\U0001d621', &['\x5a']), ('\U0001d622', &['\x61']), ('\U0001d623', &['\x62']),
+ ('\U0001d624', &['\x63']), ('\U0001d625', &['\x64']), ('\U0001d626', &['\x65']),
+ ('\U0001d627', &['\x66']), ('\U0001d628', &['\x67']), ('\U0001d629', &['\x68']),
+ ('\U0001d62a', &['\x69']), ('\U0001d62b', &['\x6a']), ('\U0001d62c', &['\x6b']),
+ ('\U0001d62d', &['\x6c']), ('\U0001d62e', &['\x6d']), ('\U0001d62f', &['\x6e']),
+ ('\U0001d630', &['\x6f']), ('\U0001d631', &['\x70']), ('\U0001d632', &['\x71']),
+ ('\U0001d633', &['\x72']), ('\U0001d634', &['\x73']), ('\U0001d635', &['\x74']),
+ ('\U0001d636', &['\x75']), ('\U0001d637', &['\x76']), ('\U0001d638', &['\x77']),
+ ('\U0001d639', &['\x78']), ('\U0001d63a', &['\x79']), ('\U0001d63b', &['\x7a']),
+ ('\U0001d63c', &['\x41']), ('\U0001d63d', &['\x42']), ('\U0001d63e', &['\x43']),
+ ('\U0001d63f', &['\x44']), ('\U0001d640', &['\x45']), ('\U0001d641', &['\x46']),
+ ('\U0001d642', &['\x47']), ('\U0001d643', &['\x48']), ('\U0001d644', &['\x49']),
+ ('\U0001d645', &['\x4a']), ('\U0001d646', &['\x4b']), ('\U0001d647', &['\x4c']),
+ ('\U0001d648', &['\x4d']), ('\U0001d649', &['\x4e']), ('\U0001d64a', &['\x4f']),
+ ('\U0001d64b', &['\x50']), ('\U0001d64c', &['\x51']), ('\U0001d64d', &['\x52']),
+ ('\U0001d64e', &['\x53']), ('\U0001d64f', &['\x54']), ('\U0001d650', &['\x55']),
+ ('\U0001d651', &['\x56']), ('\U0001d652', &['\x57']), ('\U0001d653', &['\x58']),
+ ('\U0001d654', &['\x59']), ('\U0001d655', &['\x5a']), ('\U0001d656', &['\x61']),
+ ('\U0001d657', &['\x62']), ('\U0001d658', &['\x63']), ('\U0001d659', &['\x64']),
+ ('\U0001d65a', &['\x65']), ('\U0001d65b', &['\x66']), ('\U0001d65c', &['\x67']),
+ ('\U0001d65d', &['\x68']), ('\U0001d65e', &['\x69']), ('\U0001d65f', &['\x6a']),
+ ('\U0001d660', &['\x6b']), ('\U0001d661', &['\x6c']), ('\U0001d662', &['\x6d']),
+ ('\U0001d663', &['\x6e']), ('\U0001d664', &['\x6f']), ('\U0001d665', &['\x70']),
+ ('\U0001d666', &['\x71']), ('\U0001d667', &['\x72']), ('\U0001d668', &['\x73']),
+ ('\U0001d669', &['\x74']), ('\U0001d66a', &['\x75']), ('\U0001d66b', &['\x76']),
+ ('\U0001d66c', &['\x77']), ('\U0001d66d', &['\x78']), ('\U0001d66e', &['\x79']),
+ ('\U0001d66f', &['\x7a']), ('\U0001d670', &['\x41']), ('\U0001d671', &['\x42']),
+ ('\U0001d672', &['\x43']), ('\U0001d673', &['\x44']), ('\U0001d674', &['\x45']),
+ ('\U0001d675', &['\x46']), ('\U0001d676', &['\x47']), ('\U0001d677', &['\x48']),
+ ('\U0001d678', &['\x49']), ('\U0001d679', &['\x4a']), ('\U0001d67a', &['\x4b']),
+ ('\U0001d67b', &['\x4c']), ('\U0001d67c', &['\x4d']), ('\U0001d67d', &['\x4e']),
+ ('\U0001d67e', &['\x4f']), ('\U0001d67f', &['\x50']), ('\U0001d680', &['\x51']),
+ ('\U0001d681', &['\x52']), ('\U0001d682', &['\x53']), ('\U0001d683', &['\x54']),
+ ('\U0001d684', &['\x55']), ('\U0001d685', &['\x56']), ('\U0001d686', &['\x57']),
+ ('\U0001d687', &['\x58']), ('\U0001d688', &['\x59']), ('\U0001d689', &['\x5a']),
+ ('\U0001d68a', &['\x61']), ('\U0001d68b', &['\x62']), ('\U0001d68c', &['\x63']),
+ ('\U0001d68d', &['\x64']), ('\U0001d68e', &['\x65']), ('\U0001d68f', &['\x66']),
+ ('\U0001d690', &['\x67']), ('\U0001d691', &['\x68']), ('\U0001d692', &['\x69']),
+ ('\U0001d693', &['\x6a']), ('\U0001d694', &['\x6b']), ('\U0001d695', &['\x6c']),
+ ('\U0001d696', &['\x6d']), ('\U0001d697', &['\x6e']), ('\U0001d698', &['\x6f']),
+ ('\U0001d699', &['\x70']), ('\U0001d69a', &['\x71']), ('\U0001d69b', &['\x72']),
+ ('\U0001d69c', &['\x73']), ('\U0001d69d', &['\x74']), ('\U0001d69e', &['\x75']),
+ ('\U0001d69f', &['\x76']), ('\U0001d6a0', &['\x77']), ('\U0001d6a1', &['\x78']),
+ ('\U0001d6a2', &['\x79']), ('\U0001d6a3', &['\x7a']), ('\U0001d6a4', &['\u0131']),
+ ('\U0001d6a5', &['\u0237']), ('\U0001d6a8', &['\u0391']), ('\U0001d6a9', &['\u0392']),
+ ('\U0001d6aa', &['\u0393']), ('\U0001d6ab', &['\u0394']), ('\U0001d6ac', &['\u0395']),
+ ('\U0001d6ad', &['\u0396']), ('\U0001d6ae', &['\u0397']), ('\U0001d6af', &['\u0398']),
+ ('\U0001d6b0', &['\u0399']), ('\U0001d6b1', &['\u039a']), ('\U0001d6b2', &['\u039b']),
+ ('\U0001d6b3', &['\u039c']), ('\U0001d6b4', &['\u039d']), ('\U0001d6b5', &['\u039e']),
+ ('\U0001d6b6', &['\u039f']), ('\U0001d6b7', &['\u03a0']), ('\U0001d6b8', &['\u03a1']),
+ ('\U0001d6b9', &['\u03f4']), ('\U0001d6ba', &['\u03a3']), ('\U0001d6bb', &['\u03a4']),
+ ('\U0001d6bc', &['\u03a5']), ('\U0001d6bd', &['\u03a6']), ('\U0001d6be', &['\u03a7']),
+ ('\U0001d6bf', &['\u03a8']), ('\U0001d6c0', &['\u03a9']), ('\U0001d6c1', &['\u2207']),
+ ('\U0001d6c2', &['\u03b1']), ('\U0001d6c3', &['\u03b2']), ('\U0001d6c4', &['\u03b3']),
+ ('\U0001d6c5', &['\u03b4']), ('\U0001d6c6', &['\u03b5']), ('\U0001d6c7', &['\u03b6']),
+ ('\U0001d6c8', &['\u03b7']), ('\U0001d6c9', &['\u03b8']), ('\U0001d6ca', &['\u03b9']),
+ ('\U0001d6cb', &['\u03ba']), ('\U0001d6cc', &['\u03bb']), ('\U0001d6cd', &['\u03bc']),
+ ('\U0001d6ce', &['\u03bd']), ('\U0001d6cf', &['\u03be']), ('\U0001d6d0', &['\u03bf']),
+ ('\U0001d6d1', &['\u03c0']), ('\U0001d6d2', &['\u03c1']), ('\U0001d6d3', &['\u03c2']),
+ ('\U0001d6d4', &['\u03c3']), ('\U0001d6d5', &['\u03c4']), ('\U0001d6d6', &['\u03c5']),
+ ('\U0001d6d7', &['\u03c6']), ('\U0001d6d8', &['\u03c7']), ('\U0001d6d9', &['\u03c8']),
+ ('\U0001d6da', &['\u03c9']), ('\U0001d6db', &['\u2202']), ('\U0001d6dc', &['\u03f5']),
+ ('\U0001d6dd', &['\u03d1']), ('\U0001d6de', &['\u03f0']), ('\U0001d6df', &['\u03d5']),
+ ('\U0001d6e0', &['\u03f1']), ('\U0001d6e1', &['\u03d6']), ('\U0001d6e2', &['\u0391']),
+ ('\U0001d6e3', &['\u0392']), ('\U0001d6e4', &['\u0393']), ('\U0001d6e5', &['\u0394']),
+ ('\U0001d6e6', &['\u0395']), ('\U0001d6e7', &['\u0396']), ('\U0001d6e8', &['\u0397']),
+ ('\U0001d6e9', &['\u0398']), ('\U0001d6ea', &['\u0399']), ('\U0001d6eb', &['\u039a']),
+ ('\U0001d6ec', &['\u039b']), ('\U0001d6ed', &['\u039c']), ('\U0001d6ee', &['\u039d']),
+ ('\U0001d6ef', &['\u039e']), ('\U0001d6f0', &['\u039f']), ('\U0001d6f1', &['\u03a0']),
+ ('\U0001d6f2', &['\u03a1']), ('\U0001d6f3', &['\u03f4']), ('\U0001d6f4', &['\u03a3']),
+ ('\U0001d6f5', &['\u03a4']), ('\U0001d6f6', &['\u03a5']), ('\U0001d6f7', &['\u03a6']),
+ ('\U0001d6f8', &['\u03a7']), ('\U0001d6f9', &['\u03a8']), ('\U0001d6fa', &['\u03a9']),
+ ('\U0001d6fb', &['\u2207']), ('\U0001d6fc', &['\u03b1']), ('\U0001d6fd', &['\u03b2']),
+ ('\U0001d6fe', &['\u03b3']), ('\U0001d6ff', &['\u03b4']), ('\U0001d700', &['\u03b5']),
+ ('\U0001d701', &['\u03b6']), ('\U0001d702', &['\u03b7']), ('\U0001d703', &['\u03b8']),
+ ('\U0001d704', &['\u03b9']), ('\U0001d705', &['\u03ba']), ('\U0001d706', &['\u03bb']),
+ ('\U0001d707', &['\u03bc']), ('\U0001d708', &['\u03bd']), ('\U0001d709', &['\u03be']),
+ ('\U0001d70a', &['\u03bf']), ('\U0001d70b', &['\u03c0']), ('\U0001d70c', &['\u03c1']),
+ ('\U0001d70d', &['\u03c2']), ('\U0001d70e', &['\u03c3']), ('\U0001d70f', &['\u03c4']),
+ ('\U0001d710', &['\u03c5']), ('\U0001d711', &['\u03c6']), ('\U0001d712', &['\u03c7']),
+ ('\U0001d713', &['\u03c8']), ('\U0001d714', &['\u03c9']), ('\U0001d715', &['\u2202']),
+ ('\U0001d716', &['\u03f5']), ('\U0001d717', &['\u03d1']), ('\U0001d718', &['\u03f0']),
+ ('\U0001d719', &['\u03d5']), ('\U0001d71a', &['\u03f1']), ('\U0001d71b', &['\u03d6']),
+ ('\U0001d71c', &['\u0391']), ('\U0001d71d', &['\u0392']), ('\U0001d71e', &['\u0393']),
+ ('\U0001d71f', &['\u0394']), ('\U0001d720', &['\u0395']), ('\U0001d721', &['\u0396']),
+ ('\U0001d722', &['\u0397']), ('\U0001d723', &['\u0398']), ('\U0001d724', &['\u0399']),
+ ('\U0001d725', &['\u039a']), ('\U0001d726', &['\u039b']), ('\U0001d727', &['\u039c']),
+ ('\U0001d728', &['\u039d']), ('\U0001d729', &['\u039e']), ('\U0001d72a', &['\u039f']),
+ ('\U0001d72b', &['\u03a0']), ('\U0001d72c', &['\u03a1']), ('\U0001d72d', &['\u03f4']),
+ ('\U0001d72e', &['\u03a3']), ('\U0001d72f', &['\u03a4']), ('\U0001d730', &['\u03a5']),
+ ('\U0001d731', &['\u03a6']), ('\U0001d732', &['\u03a7']), ('\U0001d733', &['\u03a8']),
+ ('\U0001d734', &['\u03a9']), ('\U0001d735', &['\u2207']), ('\U0001d736', &['\u03b1']),
+ ('\U0001d737', &['\u03b2']), ('\U0001d738', &['\u03b3']), ('\U0001d739', &['\u03b4']),
+ ('\U0001d73a', &['\u03b5']), ('\U0001d73b', &['\u03b6']), ('\U0001d73c', &['\u03b7']),
+ ('\U0001d73d', &['\u03b8']), ('\U0001d73e', &['\u03b9']), ('\U0001d73f', &['\u03ba']),
+ ('\U0001d740', &['\u03bb']), ('\U0001d741', &['\u03bc']), ('\U0001d742', &['\u03bd']),
+ ('\U0001d743', &['\u03be']), ('\U0001d744', &['\u03bf']), ('\U0001d745', &['\u03c0']),
+ ('\U0001d746', &['\u03c1']), ('\U0001d747', &['\u03c2']), ('\U0001d748', &['\u03c3']),
+ ('\U0001d749', &['\u03c4']), ('\U0001d74a', &['\u03c5']), ('\U0001d74b', &['\u03c6']),
+ ('\U0001d74c', &['\u03c7']), ('\U0001d74d', &['\u03c8']), ('\U0001d74e', &['\u03c9']),
+ ('\U0001d74f', &['\u2202']), ('\U0001d750', &['\u03f5']), ('\U0001d751', &['\u03d1']),
+ ('\U0001d752', &['\u03f0']), ('\U0001d753', &['\u03d5']), ('\U0001d754', &['\u03f1']),
+ ('\U0001d755', &['\u03d6']), ('\U0001d756', &['\u0391']), ('\U0001d757', &['\u0392']),
+ ('\U0001d758', &['\u0393']), ('\U0001d759', &['\u0394']), ('\U0001d75a', &['\u0395']),
+ ('\U0001d75b', &['\u0396']), ('\U0001d75c', &['\u0397']), ('\U0001d75d', &['\u0398']),
+ ('\U0001d75e', &['\u0399']), ('\U0001d75f', &['\u039a']), ('\U0001d760', &['\u039b']),
+ ('\U0001d761', &['\u039c']), ('\U0001d762', &['\u039d']), ('\U0001d763', &['\u039e']),
+ ('\U0001d764', &['\u039f']), ('\U0001d765', &['\u03a0']), ('\U0001d766', &['\u03a1']),
+ ('\U0001d767', &['\u03f4']), ('\U0001d768', &['\u03a3']), ('\U0001d769', &['\u03a4']),
+ ('\U0001d76a', &['\u03a5']), ('\U0001d76b', &['\u03a6']), ('\U0001d76c', &['\u03a7']),
+ ('\U0001d76d', &['\u03a8']), ('\U0001d76e', &['\u03a9']), ('\U0001d76f', &['\u2207']),
+ ('\U0001d770', &['\u03b1']), ('\U0001d771', &['\u03b2']), ('\U0001d772', &['\u03b3']),
+ ('\U0001d773', &['\u03b4']), ('\U0001d774', &['\u03b5']), ('\U0001d775', &['\u03b6']),
+ ('\U0001d776', &['\u03b7']), ('\U0001d777', &['\u03b8']), ('\U0001d778', &['\u03b9']),
+ ('\U0001d779', &['\u03ba']), ('\U0001d77a', &['\u03bb']), ('\U0001d77b', &['\u03bc']),
+ ('\U0001d77c', &['\u03bd']), ('\U0001d77d', &['\u03be']), ('\U0001d77e', &['\u03bf']),
+ ('\U0001d77f', &['\u03c0']), ('\U0001d780', &['\u03c1']), ('\U0001d781', &['\u03c2']),
+ ('\U0001d782', &['\u03c3']), ('\U0001d783', &['\u03c4']), ('\U0001d784', &['\u03c5']),
+ ('\U0001d785', &['\u03c6']), ('\U0001d786', &['\u03c7']), ('\U0001d787', &['\u03c8']),
+ ('\U0001d788', &['\u03c9']), ('\U0001d789', &['\u2202']), ('\U0001d78a', &['\u03f5']),
+ ('\U0001d78b', &['\u03d1']), ('\U0001d78c', &['\u03f0']), ('\U0001d78d', &['\u03d5']),
+ ('\U0001d78e', &['\u03f1']), ('\U0001d78f', &['\u03d6']), ('\U0001d790', &['\u0391']),
+ ('\U0001d791', &['\u0392']), ('\U0001d792', &['\u0393']), ('\U0001d793', &['\u0394']),
+ ('\U0001d794', &['\u0395']), ('\U0001d795', &['\u0396']), ('\U0001d796', &['\u0397']),
+ ('\U0001d797', &['\u0398']), ('\U0001d798', &['\u0399']), ('\U0001d799', &['\u039a']),
+ ('\U0001d79a', &['\u039b']), ('\U0001d79b', &['\u039c']), ('\U0001d79c', &['\u039d']),
+ ('\U0001d79d', &['\u039e']), ('\U0001d79e', &['\u039f']), ('\U0001d79f', &['\u03a0']),
+ ('\U0001d7a0', &['\u03a1']), ('\U0001d7a1', &['\u03f4']), ('\U0001d7a2', &['\u03a3']),
+ ('\U0001d7a3', &['\u03a4']), ('\U0001d7a4', &['\u03a5']), ('\U0001d7a5', &['\u03a6']),
+ ('\U0001d7a6', &['\u03a7']), ('\U0001d7a7', &['\u03a8']), ('\U0001d7a8', &['\u03a9']),
+ ('\U0001d7a9', &['\u2207']), ('\U0001d7aa', &['\u03b1']), ('\U0001d7ab', &['\u03b2']),
+ ('\U0001d7ac', &['\u03b3']), ('\U0001d7ad', &['\u03b4']), ('\U0001d7ae', &['\u03b5']),
+ ('\U0001d7af', &['\u03b6']), ('\U0001d7b0', &['\u03b7']), ('\U0001d7b1', &['\u03b8']),
+ ('\U0001d7b2', &['\u03b9']), ('\U0001d7b3', &['\u03ba']), ('\U0001d7b4', &['\u03bb']),
+ ('\U0001d7b5', &['\u03bc']), ('\U0001d7b6', &['\u03bd']), ('\U0001d7b7', &['\u03be']),
+ ('\U0001d7b8', &['\u03bf']), ('\U0001d7b9', &['\u03c0']), ('\U0001d7ba', &['\u03c1']),
+ ('\U0001d7bb', &['\u03c2']), ('\U0001d7bc', &['\u03c3']), ('\U0001d7bd', &['\u03c4']),
+ ('\U0001d7be', &['\u03c5']), ('\U0001d7bf', &['\u03c6']), ('\U0001d7c0', &['\u03c7']),
+ ('\U0001d7c1', &['\u03c8']), ('\U0001d7c2', &['\u03c9']), ('\U0001d7c3', &['\u2202']),
+ ('\U0001d7c4', &['\u03f5']), ('\U0001d7c5', &['\u03d1']), ('\U0001d7c6', &['\u03f0']),
+ ('\U0001d7c7', &['\u03d5']), ('\U0001d7c8', &['\u03f1']), ('\U0001d7c9', &['\u03d6']),
+ ('\U0001d7ca', &['\u03dc']), ('\U0001d7cb', &['\u03dd']), ('\U0001d7ce', &['\x30']),
+ ('\U0001d7cf', &['\x31']), ('\U0001d7d0', &['\x32']), ('\U0001d7d1', &['\x33']),
+ ('\U0001d7d2', &['\x34']), ('\U0001d7d3', &['\x35']), ('\U0001d7d4', &['\x36']),
+ ('\U0001d7d5', &['\x37']), ('\U0001d7d6', &['\x38']), ('\U0001d7d7', &['\x39']),
+ ('\U0001d7d8', &['\x30']), ('\U0001d7d9', &['\x31']), ('\U0001d7da', &['\x32']),
+ ('\U0001d7db', &['\x33']), ('\U0001d7dc', &['\x34']), ('\U0001d7dd', &['\x35']),
+ ('\U0001d7de', &['\x36']), ('\U0001d7df', &['\x37']), ('\U0001d7e0', &['\x38']),
+ ('\U0001d7e1', &['\x39']), ('\U0001d7e2', &['\x30']), ('\U0001d7e3', &['\x31']),
+ ('\U0001d7e4', &['\x32']), ('\U0001d7e5', &['\x33']), ('\U0001d7e6', &['\x34']),
+ ('\U0001d7e7', &['\x35']), ('\U0001d7e8', &['\x36']), ('\U0001d7e9', &['\x37']),
+ ('\U0001d7ea', &['\x38']), ('\U0001d7eb', &['\x39']), ('\U0001d7ec', &['\x30']),
+ ('\U0001d7ed', &['\x31']), ('\U0001d7ee', &['\x32']), ('\U0001d7ef', &['\x33']),
+ ('\U0001d7f0', &['\x34']), ('\U0001d7f1', &['\x35']), ('\U0001d7f2', &['\x36']),
+ ('\U0001d7f3', &['\x37']), ('\U0001d7f4', &['\x38']), ('\U0001d7f5', &['\x39']),
+ ('\U0001d7f6', &['\x30']), ('\U0001d7f7', &['\x31']), ('\U0001d7f8', &['\x32']),
+ ('\U0001d7f9', &['\x33']), ('\U0001d7fa', &['\x34']), ('\U0001d7fb', &['\x35']),
+ ('\U0001d7fc', &['\x36']), ('\U0001d7fd', &['\x37']), ('\U0001d7fe', &['\x38']),
+ ('\U0001d7ff', &['\x39']), ('\U0001ee00', &['\u0627']), ('\U0001ee01', &['\u0628']),
+ ('\U0001ee02', &['\u062c']), ('\U0001ee03', &['\u062f']), ('\U0001ee05', &['\u0648']),
+ ('\U0001ee06', &['\u0632']), ('\U0001ee07', &['\u062d']), ('\U0001ee08', &['\u0637']),
+ ('\U0001ee09', &['\u064a']), ('\U0001ee0a', &['\u0643']), ('\U0001ee0b', &['\u0644']),
+ ('\U0001ee0c', &['\u0645']), ('\U0001ee0d', &['\u0646']), ('\U0001ee0e', &['\u0633']),
+ ('\U0001ee0f', &['\u0639']), ('\U0001ee10', &['\u0641']), ('\U0001ee11', &['\u0635']),
+ ('\U0001ee12', &['\u0642']), ('\U0001ee13', &['\u0631']), ('\U0001ee14', &['\u0634']),
+ ('\U0001ee15', &['\u062a']), ('\U0001ee16', &['\u062b']), ('\U0001ee17', &['\u062e']),
+ ('\U0001ee18', &['\u0630']), ('\U0001ee19', &['\u0636']), ('\U0001ee1a', &['\u0638']),
+ ('\U0001ee1b', &['\u063a']), ('\U0001ee1c', &['\u066e']), ('\U0001ee1d', &['\u06ba']),
+ ('\U0001ee1e', &['\u06a1']), ('\U0001ee1f', &['\u066f']), ('\U0001ee21', &['\u0628']),
+ ('\U0001ee22', &['\u062c']), ('\U0001ee24', &['\u0647']), ('\U0001ee27', &['\u062d']),
+ ('\U0001ee29', &['\u064a']), ('\U0001ee2a', &['\u0643']), ('\U0001ee2b', &['\u0644']),
+ ('\U0001ee2c', &['\u0645']), ('\U0001ee2d', &['\u0646']), ('\U0001ee2e', &['\u0633']),
+ ('\U0001ee2f', &['\u0639']), ('\U0001ee30', &['\u0641']), ('\U0001ee31', &['\u0635']),
+ ('\U0001ee32', &['\u0642']), ('\U0001ee34', &['\u0634']), ('\U0001ee35', &['\u062a']),
+ ('\U0001ee36', &['\u062b']), ('\U0001ee37', &['\u062e']), ('\U0001ee39', &['\u0636']),
+ ('\U0001ee3b', &['\u063a']), ('\U0001ee42', &['\u062c']), ('\U0001ee47', &['\u062d']),
+ ('\U0001ee49', &['\u064a']), ('\U0001ee4b', &['\u0644']), ('\U0001ee4d', &['\u0646']),
+ ('\U0001ee4e', &['\u0633']), ('\U0001ee4f', &['\u0639']), ('\U0001ee51', &['\u0635']),
+ ('\U0001ee52', &['\u0642']), ('\U0001ee54', &['\u0634']), ('\U0001ee57', &['\u062e']),
+ ('\U0001ee59', &['\u0636']), ('\U0001ee5b', &['\u063a']), ('\U0001ee5d', &['\u06ba']),
+ ('\U0001ee5f', &['\u066f']), ('\U0001ee61', &['\u0628']), ('\U0001ee62', &['\u062c']),
+ ('\U0001ee64', &['\u0647']), ('\U0001ee67', &['\u062d']), ('\U0001ee68', &['\u0637']),
+ ('\U0001ee69', &['\u064a']), ('\U0001ee6a', &['\u0643']), ('\U0001ee6c', &['\u0645']),
+ ('\U0001ee6d', &['\u0646']), ('\U0001ee6e', &['\u0633']), ('\U0001ee6f', &['\u0639']),
+ ('\U0001ee70', &['\u0641']), ('\U0001ee71', &['\u0635']), ('\U0001ee72', &['\u0642']),
+ ('\U0001ee74', &['\u0634']), ('\U0001ee75', &['\u062a']), ('\U0001ee76', &['\u062b']),
+ ('\U0001ee77', &['\u062e']), ('\U0001ee79', &['\u0636']), ('\U0001ee7a', &['\u0638']),
+ ('\U0001ee7b', &['\u063a']), ('\U0001ee7c', &['\u066e']), ('\U0001ee7e', &['\u06a1']),
+ ('\U0001ee80', &['\u0627']), ('\U0001ee81', &['\u0628']), ('\U0001ee82', &['\u062c']),
+ ('\U0001ee83', &['\u062f']), ('\U0001ee84', &['\u0647']), ('\U0001ee85', &['\u0648']),
+ ('\U0001ee86', &['\u0632']), ('\U0001ee87', &['\u062d']), ('\U0001ee88', &['\u0637']),
+ ('\U0001ee89', &['\u064a']), ('\U0001ee8b', &['\u0644']), ('\U0001ee8c', &['\u0645']),
+ ('\U0001ee8d', &['\u0646']), ('\U0001ee8e', &['\u0633']), ('\U0001ee8f', &['\u0639']),
+ ('\U0001ee90', &['\u0641']), ('\U0001ee91', &['\u0635']), ('\U0001ee92', &['\u0642']),
+ ('\U0001ee93', &['\u0631']), ('\U0001ee94', &['\u0634']), ('\U0001ee95', &['\u062a']),
+ ('\U0001ee96', &['\u062b']), ('\U0001ee97', &['\u062e']), ('\U0001ee98', &['\u0630']),
+ ('\U0001ee99', &['\u0636']), ('\U0001ee9a', &['\u0638']), ('\U0001ee9b', &['\u063a']),
+ ('\U0001eea1', &['\u0628']), ('\U0001eea2', &['\u062c']), ('\U0001eea3', &['\u062f']),
+ ('\U0001eea5', &['\u0648']), ('\U0001eea6', &['\u0632']), ('\U0001eea7', &['\u062d']),
+ ('\U0001eea8', &['\u0637']), ('\U0001eea9', &['\u064a']), ('\U0001eeab', &['\u0644']),
+ ('\U0001eeac', &['\u0645']), ('\U0001eead', &['\u0646']), ('\U0001eeae', &['\u0633']),
+ ('\U0001eeaf', &['\u0639']), ('\U0001eeb0', &['\u0641']), ('\U0001eeb1', &['\u0635']),
+ ('\U0001eeb2', &['\u0642']), ('\U0001eeb3', &['\u0631']), ('\U0001eeb4', &['\u0634']),
+ ('\U0001eeb5', &['\u062a']), ('\U0001eeb6', &['\u062b']), ('\U0001eeb7', &['\u062e']),
+ ('\U0001eeb8', &['\u0630']), ('\U0001eeb9', &['\u0636']), ('\U0001eeba', &['\u0638']),
+ ('\U0001eebb', &['\u063a']), ('\U0001f100', &['\x30', '\x2e']), ('\U0001f101', &['\x30',
+ '\x2c']), ('\U0001f102', &['\x31', '\x2c']), ('\U0001f103', &['\x32', '\x2c']),
+ ('\U0001f104', &['\x33', '\x2c']), ('\U0001f105', &['\x34', '\x2c']), ('\U0001f106',
+ &['\x35', '\x2c']), ('\U0001f107', &['\x36', '\x2c']), ('\U0001f108', &['\x37', '\x2c']),
+ ('\U0001f109', &['\x38', '\x2c']), ('\U0001f10a', &['\x39', '\x2c']), ('\U0001f110',
+ &['\x28', '\x41', '\x29']), ('\U0001f111', &['\x28', '\x42', '\x29']), ('\U0001f112',
+ &['\x28', '\x43', '\x29']), ('\U0001f113', &['\x28', '\x44', '\x29']), ('\U0001f114',
+ &['\x28', '\x45', '\x29']), ('\U0001f115', &['\x28', '\x46', '\x29']), ('\U0001f116',
+ &['\x28', '\x47', '\x29']), ('\U0001f117', &['\x28', '\x48', '\x29']), ('\U0001f118',
+ &['\x28', '\x49', '\x29']), ('\U0001f119', &['\x28', '\x4a', '\x29']), ('\U0001f11a',
+ &['\x28', '\x4b', '\x29']), ('\U0001f11b', &['\x28', '\x4c', '\x29']), ('\U0001f11c',
+ &['\x28', '\x4d', '\x29']), ('\U0001f11d', &['\x28', '\x4e', '\x29']), ('\U0001f11e',
+ &['\x28', '\x4f', '\x29']), ('\U0001f11f', &['\x28', '\x50', '\x29']), ('\U0001f120',
+ &['\x28', '\x51', '\x29']), ('\U0001f121', &['\x28', '\x52', '\x29']), ('\U0001f122',
+ &['\x28', '\x53', '\x29']), ('\U0001f123', &['\x28', '\x54', '\x29']), ('\U0001f124',
+ &['\x28', '\x55', '\x29']), ('\U0001f125', &['\x28', '\x56', '\x29']), ('\U0001f126',
+ &['\x28', '\x57', '\x29']), ('\U0001f127', &['\x28', '\x58', '\x29']), ('\U0001f128',
+ &['\x28', '\x59', '\x29']), ('\U0001f129', &['\x28', '\x5a', '\x29']), ('\U0001f12a',
+ &['\u3014', '\x53', '\u3015']), ('\U0001f12b', &['\x43']), ('\U0001f12c', &['\x52']),
+ ('\U0001f12d', &['\x43', '\x44']), ('\U0001f12e', &['\x57', '\x5a']), ('\U0001f130',
+ &['\x41']), ('\U0001f131', &['\x42']), ('\U0001f132', &['\x43']), ('\U0001f133', &['\x44']),
+ ('\U0001f134', &['\x45']), ('\U0001f135', &['\x46']), ('\U0001f136', &['\x47']),
+ ('\U0001f137', &['\x48']), ('\U0001f138', &['\x49']), ('\U0001f139', &['\x4a']),
+ ('\U0001f13a', &['\x4b']), ('\U0001f13b', &['\x4c']), ('\U0001f13c', &['\x4d']),
+ ('\U0001f13d', &['\x4e']), ('\U0001f13e', &['\x4f']), ('\U0001f13f', &['\x50']),
+ ('\U0001f140', &['\x51']), ('\U0001f141', &['\x52']), ('\U0001f142', &['\x53']),
+ ('\U0001f143', &['\x54']), ('\U0001f144', &['\x55']), ('\U0001f145', &['\x56']),
+ ('\U0001f146', &['\x57']), ('\U0001f147', &['\x58']), ('\U0001f148', &['\x59']),
+ ('\U0001f149', &['\x5a']), ('\U0001f14a', &['\x48', '\x56']), ('\U0001f14b', &['\x4d',
+ '\x56']), ('\U0001f14c', &['\x53', '\x44']), ('\U0001f14d', &['\x53', '\x53']),
+ ('\U0001f14e', &['\x50', '\x50', '\x56']), ('\U0001f14f', &['\x57', '\x43']), ('\U0001f16a',
+ &['\x4d', '\x43']), ('\U0001f16b', &['\x4d', '\x44']), ('\U0001f190', &['\x44', '\x4a']),
+ ('\U0001f200', &['\u307b', '\u304b']), ('\U0001f201', &['\u30b3', '\u30b3']), ('\U0001f202',
+ &['\u30b5']), ('\U0001f210', &['\u624b']), ('\U0001f211', &['\u5b57']), ('\U0001f212',
+ &['\u53cc']), ('\U0001f213', &['\u30c7']), ('\U0001f214', &['\u4e8c']), ('\U0001f215',
+ &['\u591a']), ('\U0001f216', &['\u89e3']), ('\U0001f217', &['\u5929']), ('\U0001f218',
+ &['\u4ea4']), ('\U0001f219', &['\u6620']), ('\U0001f21a', &['\u7121']), ('\U0001f21b',
+ &['\u6599']), ('\U0001f21c', &['\u524d']), ('\U0001f21d', &['\u5f8c']), ('\U0001f21e',
+ &['\u518d']), ('\U0001f21f', &['\u65b0']), ('\U0001f220', &['\u521d']), ('\U0001f221',
+ &['\u7d42']), ('\U0001f222', &['\u751f']), ('\U0001f223', &['\u8ca9']), ('\U0001f224',
+ &['\u58f0']), ('\U0001f225', &['\u5439']), ('\U0001f226', &['\u6f14']), ('\U0001f227',
+ &['\u6295']), ('\U0001f228', &['\u6355']), ('\U0001f229', &['\u4e00']), ('\U0001f22a',
+ &['\u4e09']), ('\U0001f22b', &['\u904a']), ('\U0001f22c', &['\u5de6']), ('\U0001f22d',
+ &['\u4e2d']), ('\U0001f22e', &['\u53f3']), ('\U0001f22f', &['\u6307']), ('\U0001f230',
+ &['\u8d70']), ('\U0001f231', &['\u6253']), ('\U0001f232', &['\u7981']), ('\U0001f233',
+ &['\u7a7a']), ('\U0001f234', &['\u5408']), ('\U0001f235', &['\u6e80']), ('\U0001f236',
+ &['\u6709']), ('\U0001f237', &['\u6708']), ('\U0001f238', &['\u7533']), ('\U0001f239',
+ &['\u5272']), ('\U0001f23a', &['\u55b6']), ('\U0001f240', &['\u3014', '\u672c', '\u3015']),
+ ('\U0001f241', &['\u3014', '\u4e09', '\u3015']), ('\U0001f242', &['\u3014', '\u4e8c',
+ '\u3015']), ('\U0001f243', &['\u3014', '\u5b89', '\u3015']), ('\U0001f244', &['\u3014',
+ '\u70b9', '\u3015']), ('\U0001f245', &['\u3014', '\u6253', '\u3015']), ('\U0001f246',
+ &['\u3014', '\u76d7', '\u3015']), ('\U0001f247', &['\u3014', '\u52dd', '\u3015']),
+ ('\U0001f248', &['\u3014', '\u6557', '\u3015']), ('\U0001f250', &['\u5f97']), ('\U0001f251',
+ &['\u53ef'])
+ ];
+
+
+ fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
+ use core::option::{Some, None};
+ use core::cmp::{Equal, Less, Greater};
+ use core::slice::ImmutableVector;
+ match r.bsearch(|&(lo, hi, _)| {
+ if lo <= c && c <= hi { Equal }
+ else if hi < c { Less }
+ else { Greater }
+ }) {
+ Some(idx) => {
+ let (_, _, result) = r[idx];
+ result
+ }
+ None => 0
+ }
+ }
+
+ static combining_class_table: &'static [(char, char, u8)] = &[
+ ('\u0300', '\u0314', 230), ('\u0315', '\u0315', 232), ('\u0316', '\u0319', 220), ('\u031a',
+ '\u031a', 232), ('\u031b', '\u031b', 216), ('\u031c', '\u0320', 220), ('\u0321', '\u0322',
+ 202), ('\u0323', '\u0326', 220), ('\u0327', '\u0328', 202), ('\u0329', '\u0333', 220),
+ ('\u0334', '\u0338', 1), ('\u0339', '\u033c', 220), ('\u033d', '\u0344', 230), ('\u0345',
+ '\u0345', 240), ('\u0346', '\u0346', 230), ('\u0347', '\u0349', 220), ('\u034a', '\u034c',
+ 230), ('\u034d', '\u034e', 220), ('\u0350', '\u0352', 230), ('\u0353', '\u0356', 220),
+ ('\u0357', '\u0357', 230), ('\u0358', '\u0358', 232), ('\u0359', '\u035a', 220), ('\u035b',
+ '\u035b', 230), ('\u035c', '\u035c', 233), ('\u035d', '\u035e', 234), ('\u035f', '\u035f',
+ 233), ('\u0360', '\u0361', 234), ('\u0362', '\u0362', 233), ('\u0363', '\u036f', 230),
+ ('\u0483', '\u0487', 230), ('\u0591', '\u0591', 220), ('\u0592', '\u0595', 230), ('\u0596',
+ '\u0596', 220), ('\u0597', '\u0599', 230), ('\u059a', '\u059a', 222), ('\u059b', '\u059b',
+ 220), ('\u059c', '\u05a1', 230), ('\u05a2', '\u05a7', 220), ('\u05a8', '\u05a9', 230),
+ ('\u05aa', '\u05aa', 220), ('\u05ab', '\u05ac', 230), ('\u05ad', '\u05ad', 222), ('\u05ae',
+ '\u05ae', 228), ('\u05af', '\u05af', 230), ('\u05b0', '\u05b0', 10), ('\u05b1', '\u05b1',
+ 11), ('\u05b2', '\u05b2', 12), ('\u05b3', '\u05b3', 13), ('\u05b4', '\u05b4', 14),
+ ('\u05b5', '\u05b5', 15), ('\u05b6', '\u05b6', 16), ('\u05b7', '\u05b7', 17), ('\u05b8',
+ '\u05b8', 18), ('\u05b9', '\u05ba', 19), ('\u05bb', '\u05bb', 20), ('\u05bc', '\u05bc', 21),
+ ('\u05bd', '\u05bd', 22), ('\u05bf', '\u05bf', 23), ('\u05c1', '\u05c1', 24), ('\u05c2',
+ '\u05c2', 25), ('\u05c4', '\u05c4', 230), ('\u05c5', '\u05c5', 220), ('\u05c7', '\u05c7',
+ 18), ('\u0610', '\u0617', 230), ('\u0618', '\u0618', 30), ('\u0619', '\u0619', 31),
+ ('\u061a', '\u061a', 32), ('\u064b', '\u064b', 27), ('\u064c', '\u064c', 28), ('\u064d',
+ '\u064d', 29), ('\u064e', '\u064e', 30), ('\u064f', '\u064f', 31), ('\u0650', '\u0650', 32),
+ ('\u0651', '\u0651', 33), ('\u0652', '\u0652', 34), ('\u0653', '\u0654', 230), ('\u0655',
+ '\u0656', 220), ('\u0657', '\u065b', 230), ('\u065c', '\u065c', 220), ('\u065d', '\u065e',
+ 230), ('\u065f', '\u065f', 220), ('\u0670', '\u0670', 35), ('\u06d6', '\u06dc', 230),
+ ('\u06df', '\u06e2', 230), ('\u06e3', '\u06e3', 220), ('\u06e4', '\u06e4', 230), ('\u06e7',
+ '\u06e8', 230), ('\u06ea', '\u06ea', 220), ('\u06eb', '\u06ec', 230), ('\u06ed', '\u06ed',
+ 220), ('\u0711', '\u0711', 36), ('\u0730', '\u0730', 230), ('\u0731', '\u0731', 220),
+ ('\u0732', '\u0733', 230), ('\u0734', '\u0734', 220), ('\u0735', '\u0736', 230), ('\u0737',
+ '\u0739', 220), ('\u073a', '\u073a', 230), ('\u073b', '\u073c', 220), ('\u073d', '\u073d',
+ 230), ('\u073e', '\u073e', 220), ('\u073f', '\u0741', 230), ('\u0742', '\u0742', 220),
+ ('\u0743', '\u0743', 230), ('\u0744', '\u0744', 220), ('\u0745', '\u0745', 230), ('\u0746',
+ '\u0746', 220), ('\u0747', '\u0747', 230), ('\u0748', '\u0748', 220), ('\u0749', '\u074a',
+ 230), ('\u07eb', '\u07f1', 230), ('\u07f2', '\u07f2', 220), ('\u07f3', '\u07f3', 230),
+ ('\u0816', '\u0819', 230), ('\u081b', '\u0823', 230), ('\u0825', '\u0827', 230), ('\u0829',
+ '\u082d', 230), ('\u0859', '\u085b', 220), ('\u08e4', '\u08e5', 230), ('\u08e6', '\u08e6',
+ 220), ('\u08e7', '\u08e8', 230), ('\u08e9', '\u08e9', 220), ('\u08ea', '\u08ec', 230),
+ ('\u08ed', '\u08ef', 220), ('\u08f0', '\u08f0', 27), ('\u08f1', '\u08f1', 28), ('\u08f2',
+ '\u08f2', 29), ('\u08f3', '\u08f5', 230), ('\u08f6', '\u08f6', 220), ('\u08f7', '\u08f8',
+ 230), ('\u08f9', '\u08fa', 220), ('\u08fb', '\u08ff', 230), ('\u093c', '\u093c', 7),
+ ('\u094d', '\u094d', 9), ('\u0951', '\u0951', 230), ('\u0952', '\u0952', 220), ('\u0953',
+ '\u0954', 230), ('\u09bc', '\u09bc', 7), ('\u09cd', '\u09cd', 9), ('\u0a3c', '\u0a3c', 7),
+ ('\u0a4d', '\u0a4d', 9), ('\u0abc', '\u0abc', 7), ('\u0acd', '\u0acd', 9), ('\u0b3c',
+ '\u0b3c', 7), ('\u0b4d', '\u0b4d', 9), ('\u0bcd', '\u0bcd', 9), ('\u0c4d', '\u0c4d', 9),
+ ('\u0c55', '\u0c55', 84), ('\u0c56', '\u0c56', 91), ('\u0cbc', '\u0cbc', 7), ('\u0ccd',
+ '\u0ccd', 9), ('\u0d4d', '\u0d4d', 9), ('\u0dca', '\u0dca', 9), ('\u0e38', '\u0e39', 103),
+ ('\u0e3a', '\u0e3a', 9), ('\u0e48', '\u0e4b', 107), ('\u0eb8', '\u0eb9', 118), ('\u0ec8',
+ '\u0ecb', 122), ('\u0f18', '\u0f19', 220), ('\u0f35', '\u0f35', 220), ('\u0f37', '\u0f37',
+ 220), ('\u0f39', '\u0f39', 216), ('\u0f71', '\u0f71', 129), ('\u0f72', '\u0f72', 130),
+ ('\u0f74', '\u0f74', 132), ('\u0f7a', '\u0f7d', 130), ('\u0f80', '\u0f80', 130), ('\u0f82',
+ '\u0f83', 230), ('\u0f84', '\u0f84', 9), ('\u0f86', '\u0f87', 230), ('\u0fc6', '\u0fc6',
+ 220), ('\u1037', '\u1037', 7), ('\u1039', '\u103a', 9), ('\u108d', '\u108d', 220),
+ ('\u135d', '\u135f', 230), ('\u1714', '\u1714', 9), ('\u1734', '\u1734', 9), ('\u17d2',
+ '\u17d2', 9), ('\u17dd', '\u17dd', 230), ('\u18a9', '\u18a9', 228), ('\u1939', '\u1939',
+ 222), ('\u193a', '\u193a', 230), ('\u193b', '\u193b', 220), ('\u1a17', '\u1a17', 230),
+ ('\u1a18', '\u1a18', 220), ('\u1a60', '\u1a60', 9), ('\u1a75', '\u1a7c', 230), ('\u1a7f',
+ '\u1a7f', 220), ('\u1ab0', '\u1ab4', 230), ('\u1ab5', '\u1aba', 220), ('\u1abb', '\u1abc',
+ 230), ('\u1abd', '\u1abd', 220), ('\u1b34', '\u1b34', 7), ('\u1b44', '\u1b44', 9),
+ ('\u1b6b', '\u1b6b', 230), ('\u1b6c', '\u1b6c', 220), ('\u1b6d', '\u1b73', 230), ('\u1baa',
+ '\u1bab', 9), ('\u1be6', '\u1be6', 7), ('\u1bf2', '\u1bf3', 9), ('\u1c37', '\u1c37', 7),
+ ('\u1cd0', '\u1cd2', 230), ('\u1cd4', '\u1cd4', 1), ('\u1cd5', '\u1cd9', 220), ('\u1cda',
+ '\u1cdb', 230), ('\u1cdc', '\u1cdf', 220), ('\u1ce0', '\u1ce0', 230), ('\u1ce2', '\u1ce8',
+ 1), ('\u1ced', '\u1ced', 220), ('\u1cf4', '\u1cf4', 230), ('\u1cf8', '\u1cf9', 230),
+ ('\u1dc0', '\u1dc1', 230), ('\u1dc2', '\u1dc2', 220), ('\u1dc3', '\u1dc9', 230), ('\u1dca',
+ '\u1dca', 220), ('\u1dcb', '\u1dcc', 230), ('\u1dcd', '\u1dcd', 234), ('\u1dce', '\u1dce',
+ 214), ('\u1dcf', '\u1dcf', 220), ('\u1dd0', '\u1dd0', 202), ('\u1dd1', '\u1df5', 230),
+ ('\u1dfc', '\u1dfc', 233), ('\u1dfd', '\u1dfd', 220), ('\u1dfe', '\u1dfe', 230), ('\u1dff',
+ '\u1dff', 220), ('\u20d0', '\u20d1', 230), ('\u20d2', '\u20d3', 1), ('\u20d4', '\u20d7',
+ 230), ('\u20d8', '\u20da', 1), ('\u20db', '\u20dc', 230), ('\u20e1', '\u20e1', 230),
+ ('\u20e5', '\u20e6', 1), ('\u20e7', '\u20e7', 230), ('\u20e8', '\u20e8', 220), ('\u20e9',
+ '\u20e9', 230), ('\u20ea', '\u20eb', 1), ('\u20ec', '\u20ef', 220), ('\u20f0', '\u20f0',
+ 230), ('\u2cef', '\u2cf1', 230), ('\u2d7f', '\u2d7f', 9), ('\u2de0', '\u2dff', 230),
+ ('\u302a', '\u302a', 218), ('\u302b', '\u302b', 228), ('\u302c', '\u302c', 232), ('\u302d',
+ '\u302d', 222), ('\u302e', '\u302f', 224), ('\u3099', '\u309a', 8), ('\ua66f', '\ua66f',
+ 230), ('\ua674', '\ua67d', 230), ('\ua69f', '\ua69f', 230), ('\ua6f0', '\ua6f1', 230),
+ ('\ua806', '\ua806', 9), ('\ua8c4', '\ua8c4', 9), ('\ua8e0', '\ua8f1', 230), ('\ua92b',
+ '\ua92d', 220), ('\ua953', '\ua953', 9), ('\ua9b3', '\ua9b3', 7), ('\ua9c0', '\ua9c0', 9),
+ ('\uaab0', '\uaab0', 230), ('\uaab2', '\uaab3', 230), ('\uaab4', '\uaab4', 220), ('\uaab7',
+ '\uaab8', 230), ('\uaabe', '\uaabf', 230), ('\uaac1', '\uaac1', 230), ('\uaaf6', '\uaaf6',
+ 9), ('\uabed', '\uabed', 9), ('\ufb1e', '\ufb1e', 26), ('\ufe20', '\ufe26', 230), ('\ufe27',
+ '\ufe2d', 220), ('\U000101fd', '\U000101fd', 220), ('\U000102e0', '\U000102e0', 220),
+ ('\U00010376', '\U0001037a', 230), ('\U00010a0d', '\U00010a0d', 220), ('\U00010a0f',
+ '\U00010a0f', 230), ('\U00010a38', '\U00010a38', 230), ('\U00010a39', '\U00010a39', 1),
+ ('\U00010a3a', '\U00010a3a', 220), ('\U00010a3f', '\U00010a3f', 9), ('\U00010ae5',
+ '\U00010ae5', 230), ('\U00010ae6', '\U00010ae6', 220), ('\U00011046', '\U00011046', 9),
+ ('\U0001107f', '\U0001107f', 9), ('\U000110b9', '\U000110b9', 9), ('\U000110ba',
+ '\U000110ba', 7), ('\U00011100', '\U00011102', 230), ('\U00011133', '\U00011134', 9),
+ ('\U00011173', '\U00011173', 7), ('\U000111c0', '\U000111c0', 9), ('\U00011235',
+ '\U00011235', 9), ('\U00011236', '\U00011236', 7), ('\U000112e9', '\U000112e9', 7),
+ ('\U000112ea', '\U000112ea', 9), ('\U0001133c', '\U0001133c', 7), ('\U0001134d',
+ '\U0001134d', 9), ('\U00011366', '\U0001136c', 230), ('\U00011370', '\U00011374', 230),
+ ('\U000114c2', '\U000114c2', 9), ('\U000114c3', '\U000114c3', 7), ('\U000115bf',
+ '\U000115bf', 9), ('\U000115c0', '\U000115c0', 7), ('\U0001163f', '\U0001163f', 9),
+ ('\U000116b6', '\U000116b6', 9), ('\U000116b7', '\U000116b7', 7), ('\U00016af0',
+ '\U00016af4', 1), ('\U00016b30', '\U00016b36', 230), ('\U0001bc9e', '\U0001bc9e', 1),
+ ('\U0001d165', '\U0001d166', 216), ('\U0001d167', '\U0001d169', 1), ('\U0001d16d',
+ '\U0001d16d', 226), ('\U0001d16e', '\U0001d172', 216), ('\U0001d17b', '\U0001d182', 220),
+ ('\U0001d185', '\U0001d189', 230), ('\U0001d18a', '\U0001d18b', 220), ('\U0001d1aa',
+ '\U0001d1ad', 230), ('\U0001d242', '\U0001d244', 230), ('\U0001e8d0', '\U0001e8d6', 220)
+ ];
+
+ pub fn canonical_combining_class(c: char) -> u8 {
+ bsearch_range_value_table(c, combining_class_table)
+ }
+
+}
+
+pub mod conversions {
+ use core::cmp::{Equal, Less, Greater};
+ use core::slice::ImmutableVector;
+ use core::tuple::Tuple2;
+ use core::option::{Option, Some, None};
+
+ pub fn to_lower(c: char) -> char {
+ match bsearch_case_table(c, LuLl_table) {
+ None => c,
+ Some(index) => LuLl_table[index].val1()
+ }
+ }
+
+ pub fn to_upper(c: char) -> char {
+ match bsearch_case_table(c, LlLu_table) {
+ None => c,
+ Some(index) => LlLu_table[index].val1()
+ }
+ }
+
+ fn bsearch_case_table(c: char, table: &'static [(char, char)]) -> Option<uint> {
+ table.bsearch(|&(key, _)| {
+ if c == key { Equal }
+ else if key < c { Less }
+ else { Greater }
+ })
+ }
+
+ static LuLl_table: &'static [(char, char)] = &[
+ ('\x41', '\x61'), ('\x42', '\x62'), ('\x43', '\x63'), ('\x44', '\x64'), ('\x45', '\x65'),
+ ('\x46', '\x66'), ('\x47', '\x67'), ('\x48', '\x68'), ('\x49', '\x69'), ('\x4a', '\x6a'),
+ ('\x4b', '\x6b'), ('\x4c', '\x6c'), ('\x4d', '\x6d'), ('\x4e', '\x6e'), ('\x4f', '\x6f'),
+ ('\x50', '\x70'), ('\x51', '\x71'), ('\x52', '\x72'), ('\x53', '\x73'), ('\x54', '\x74'),
+ ('\x55', '\x75'), ('\x56', '\x76'), ('\x57', '\x77'), ('\x58', '\x78'), ('\x59', '\x79'),
+ ('\x5a', '\x7a'), ('\xc0', '\xe0'), ('\xc1', '\xe1'), ('\xc2', '\xe2'), ('\xc3', '\xe3'),
+ ('\xc4', '\xe4'), ('\xc5', '\xe5'), ('\xc6', '\xe6'), ('\xc7', '\xe7'), ('\xc8', '\xe8'),
+ ('\xc9', '\xe9'), ('\xca', '\xea'), ('\xcb', '\xeb'), ('\xcc', '\xec'), ('\xcd', '\xed'),
+ ('\xce', '\xee'), ('\xcf', '\xef'), ('\xd0', '\xf0'), ('\xd1', '\xf1'), ('\xd2', '\xf2'),
+ ('\xd3', '\xf3'), ('\xd4', '\xf4'), ('\xd5', '\xf5'), ('\xd6', '\xf6'), ('\xd8', '\xf8'),
+ ('\xd9', '\xf9'), ('\xda', '\xfa'), ('\xdb', '\xfb'), ('\xdc', '\xfc'), ('\xdd', '\xfd'),
+ ('\xde', '\xfe'), ('\u0100', '\u0101'), ('\u0102', '\u0103'), ('\u0104', '\u0105'),
+ ('\u0106', '\u0107'), ('\u0108', '\u0109'), ('\u010a', '\u010b'), ('\u010c', '\u010d'),
+ ('\u010e', '\u010f'), ('\u0110', '\u0111'), ('\u0112', '\u0113'), ('\u0114', '\u0115'),
+ ('\u0116', '\u0117'), ('\u0118', '\u0119'), ('\u011a', '\u011b'), ('\u011c', '\u011d'),
+ ('\u011e', '\u011f'), ('\u0120', '\u0121'), ('\u0122', '\u0123'), ('\u0124', '\u0125'),
+ ('\u0126', '\u0127'), ('\u0128', '\u0129'), ('\u012a', '\u012b'), ('\u012c', '\u012d'),
+ ('\u012e', '\u012f'), ('\u0130', '\x69'), ('\u0132', '\u0133'), ('\u0134', '\u0135'),
+ ('\u0136', '\u0137'), ('\u0139', '\u013a'), ('\u013b', '\u013c'), ('\u013d', '\u013e'),
+ ('\u013f', '\u0140'), ('\u0141', '\u0142'), ('\u0143', '\u0144'), ('\u0145', '\u0146'),
+ ('\u0147', '\u0148'), ('\u014a', '\u014b'), ('\u014c', '\u014d'), ('\u014e', '\u014f'),
+ ('\u0150', '\u0151'), ('\u0152', '\u0153'), ('\u0154', '\u0155'), ('\u0156', '\u0157'),
+ ('\u0158', '\u0159'), ('\u015a', '\u015b'), ('\u015c', '\u015d'), ('\u015e', '\u015f'),
+ ('\u0160', '\u0161'), ('\u0162', '\u0163'), ('\u0164', '\u0165'), ('\u0166', '\u0167'),
+ ('\u0168', '\u0169'), ('\u016a', '\u016b'), ('\u016c', '\u016d'), ('\u016e', '\u016f'),
+ ('\u0170', '\u0171'), ('\u0172', '\u0173'), ('\u0174', '\u0175'), ('\u0176', '\u0177'),
+ ('\u0178', '\xff'), ('\u0179', '\u017a'), ('\u017b', '\u017c'), ('\u017d', '\u017e'),
+ ('\u0181', '\u0253'), ('\u0182', '\u0183'), ('\u0184', '\u0185'), ('\u0186', '\u0254'),
+ ('\u0187', '\u0188'), ('\u0189', '\u0256'), ('\u018a', '\u0257'), ('\u018b', '\u018c'),
+ ('\u018e', '\u01dd'), ('\u018f', '\u0259'), ('\u0190', '\u025b'), ('\u0191', '\u0192'),
+ ('\u0193', '\u0260'), ('\u0194', '\u0263'), ('\u0196', '\u0269'), ('\u0197', '\u0268'),
+ ('\u0198', '\u0199'), ('\u019c', '\u026f'), ('\u019d', '\u0272'), ('\u019f', '\u0275'),
+ ('\u01a0', '\u01a1'), ('\u01a2', '\u01a3'), ('\u01a4', '\u01a5'), ('\u01a6', '\u0280'),
+ ('\u01a7', '\u01a8'), ('\u01a9', '\u0283'), ('\u01ac', '\u01ad'), ('\u01ae', '\u0288'),
+ ('\u01af', '\u01b0'), ('\u01b1', '\u028a'), ('\u01b2', '\u028b'), ('\u01b3', '\u01b4'),
+ ('\u01b5', '\u01b6'), ('\u01b7', '\u0292'), ('\u01b8', '\u01b9'), ('\u01bc', '\u01bd'),
+ ('\u01c4', '\u01c6'), ('\u01c7', '\u01c9'), ('\u01ca', '\u01cc'), ('\u01cd', '\u01ce'),
+ ('\u01cf', '\u01d0'), ('\u01d1', '\u01d2'), ('\u01d3', '\u01d4'), ('\u01d5', '\u01d6'),
+ ('\u01d7', '\u01d8'), ('\u01d9', '\u01da'), ('\u01db', '\u01dc'), ('\u01de', '\u01df'),
+ ('\u01e0', '\u01e1'), ('\u01e2', '\u01e3'), ('\u01e4', '\u01e5'), ('\u01e6', '\u01e7'),
+ ('\u01e8', '\u01e9'), ('\u01ea', '\u01eb'), ('\u01ec', '\u01ed'), ('\u01ee', '\u01ef'),
+ ('\u01f1', '\u01f3'), ('\u01f4', '\u01f5'), ('\u01f6', '\u0195'), ('\u01f7', '\u01bf'),
+ ('\u01f8', '\u01f9'), ('\u01fa', '\u01fb'), ('\u01fc', '\u01fd'), ('\u01fe', '\u01ff'),
+ ('\u0200', '\u0201'), ('\u0202', '\u0203'), ('\u0204', '\u0205'), ('\u0206', '\u0207'),
+ ('\u0208', '\u0209'), ('\u020a', '\u020b'), ('\u020c', '\u020d'), ('\u020e', '\u020f'),
+ ('\u0210', '\u0211'), ('\u0212', '\u0213'), ('\u0214', '\u0215'), ('\u0216', '\u0217'),
+ ('\u0218', '\u0219'), ('\u021a', '\u021b'), ('\u021c', '\u021d'), ('\u021e', '\u021f'),
+ ('\u0220', '\u019e'), ('\u0222', '\u0223'), ('\u0224', '\u0225'), ('\u0226', '\u0227'),
+ ('\u0228', '\u0229'), ('\u022a', '\u022b'), ('\u022c', '\u022d'), ('\u022e', '\u022f'),
+ ('\u0230', '\u0231'), ('\u0232', '\u0233'), ('\u023a', '\u2c65'), ('\u023b', '\u023c'),
+ ('\u023d', '\u019a'), ('\u023e', '\u2c66'), ('\u0241', '\u0242'), ('\u0243', '\u0180'),
+ ('\u0244', '\u0289'), ('\u0245', '\u028c'), ('\u0246', '\u0247'), ('\u0248', '\u0249'),
+ ('\u024a', '\u024b'), ('\u024c', '\u024d'), ('\u024e', '\u024f'), ('\u0370', '\u0371'),
+ ('\u0372', '\u0373'), ('\u0376', '\u0377'), ('\u037f', '\u03f3'), ('\u0386', '\u03ac'),
+ ('\u0388', '\u03ad'), ('\u0389', '\u03ae'), ('\u038a', '\u03af'), ('\u038c', '\u03cc'),
+ ('\u038e', '\u03cd'), ('\u038f', '\u03ce'), ('\u0391', '\u03b1'), ('\u0392', '\u03b2'),
+ ('\u0393', '\u03b3'), ('\u0394', '\u03b4'), ('\u0395', '\u03b5'), ('\u0396', '\u03b6'),
+ ('\u0397', '\u03b7'), ('\u0398', '\u03b8'), ('\u0399', '\u03b9'), ('\u039a', '\u03ba'),
+ ('\u039b', '\u03bb'), ('\u039c', '\u03bc'), ('\u039d', '\u03bd'), ('\u039e', '\u03be'),
+ ('\u039f', '\u03bf'), ('\u03a0', '\u03c0'), ('\u03a1', '\u03c1'), ('\u03a3', '\u03c3'),
+ ('\u03a4', '\u03c4'), ('\u03a5', '\u03c5'), ('\u03a6', '\u03c6'), ('\u03a7', '\u03c7'),
+ ('\u03a8', '\u03c8'), ('\u03a9', '\u03c9'), ('\u03aa', '\u03ca'), ('\u03ab', '\u03cb'),
+ ('\u03cf', '\u03d7'), ('\u03d8', '\u03d9'), ('\u03da', '\u03db'), ('\u03dc', '\u03dd'),
+ ('\u03de', '\u03df'), ('\u03e0', '\u03e1'), ('\u03e2', '\u03e3'), ('\u03e4', '\u03e5'),
+ ('\u03e6', '\u03e7'), ('\u03e8', '\u03e9'), ('\u03ea', '\u03eb'), ('\u03ec', '\u03ed'),
+ ('\u03ee', '\u03ef'), ('\u03f4', '\u03b8'), ('\u03f7', '\u03f8'), ('\u03f9', '\u03f2'),
+ ('\u03fa', '\u03fb'), ('\u03fd', '\u037b'), ('\u03fe', '\u037c'), ('\u03ff', '\u037d'),
+ ('\u0400', '\u0450'), ('\u0401', '\u0451'), ('\u0402', '\u0452'), ('\u0403', '\u0453'),
+ ('\u0404', '\u0454'), ('\u0405', '\u0455'), ('\u0406', '\u0456'), ('\u0407', '\u0457'),
+ ('\u0408', '\u0458'), ('\u0409', '\u0459'), ('\u040a', '\u045a'), ('\u040b', '\u045b'),
+ ('\u040c', '\u045c'), ('\u040d', '\u045d'), ('\u040e', '\u045e'), ('\u040f', '\u045f'),
+ ('\u0410', '\u0430'), ('\u0411', '\u0431'), ('\u0412', '\u0432'), ('\u0413', '\u0433'),
+ ('\u0414', '\u0434'), ('\u0415', '\u0435'), ('\u0416', '\u0436'), ('\u0417', '\u0437'),
+ ('\u0418', '\u0438'), ('\u0419', '\u0439'), ('\u041a', '\u043a'), ('\u041b', '\u043b'),
+ ('\u041c', '\u043c'), ('\u041d', '\u043d'), ('\u041e', '\u043e'), ('\u041f', '\u043f'),
+ ('\u0420', '\u0440'), ('\u0421', '\u0441'), ('\u0422', '\u0442'), ('\u0423', '\u0443'),
+ ('\u0424', '\u0444'), ('\u0425', '\u0445'), ('\u0426', '\u0446'), ('\u0427', '\u0447'),
+ ('\u0428', '\u0448'), ('\u0429', '\u0449'), ('\u042a', '\u044a'), ('\u042b', '\u044b'),
+ ('\u042c', '\u044c'), ('\u042d', '\u044d'), ('\u042e', '\u044e'), ('\u042f', '\u044f'),
+ ('\u0460', '\u0461'), ('\u0462', '\u0463'), ('\u0464', '\u0465'), ('\u0466', '\u0467'),
+ ('\u0468', '\u0469'), ('\u046a', '\u046b'), ('\u046c', '\u046d'), ('\u046e', '\u046f'),
+ ('\u0470', '\u0471'), ('\u0472', '\u0473'), ('\u0474', '\u0475'), ('\u0476', '\u0477'),
+ ('\u0478', '\u0479'), ('\u047a', '\u047b'), ('\u047c', '\u047d'), ('\u047e', '\u047f'),
+ ('\u0480', '\u0481'), ('\u048a', '\u048b'), ('\u048c', '\u048d'), ('\u048e', '\u048f'),
+ ('\u0490', '\u0491'), ('\u0492', '\u0493'), ('\u0494', '\u0495'), ('\u0496', '\u0497'),
+ ('\u0498', '\u0499'), ('\u049a', '\u049b'), ('\u049c', '\u049d'), ('\u049e', '\u049f'),
+ ('\u04a0', '\u04a1'), ('\u04a2', '\u04a3'), ('\u04a4', '\u04a5'), ('\u04a6', '\u04a7'),
+ ('\u04a8', '\u04a9'), ('\u04aa', '\u04ab'), ('\u04ac', '\u04ad'), ('\u04ae', '\u04af'),
+ ('\u04b0', '\u04b1'), ('\u04b2', '\u04b3'), ('\u04b4', '\u04b5'), ('\u04b6', '\u04b7'),
+ ('\u04b8', '\u04b9'), ('\u04ba', '\u04bb'), ('\u04bc', '\u04bd'), ('\u04be', '\u04bf'),
+ ('\u04c0', '\u04cf'), ('\u04c1', '\u04c2'), ('\u04c3', '\u04c4'), ('\u04c5', '\u04c6'),
+ ('\u04c7', '\u04c8'), ('\u04c9', '\u04ca'), ('\u04cb', '\u04cc'), ('\u04cd', '\u04ce'),
+ ('\u04d0', '\u04d1'), ('\u04d2', '\u04d3'), ('\u04d4', '\u04d5'), ('\u04d6', '\u04d7'),
+ ('\u04d8', '\u04d9'), ('\u04da', '\u04db'), ('\u04dc', '\u04dd'), ('\u04de', '\u04df'),
+ ('\u04e0', '\u04e1'), ('\u04e2', '\u04e3'), ('\u04e4', '\u04e5'), ('\u04e6', '\u04e7'),
+ ('\u04e8', '\u04e9'), ('\u04ea', '\u04eb'), ('\u04ec', '\u04ed'), ('\u04ee', '\u04ef'),
+ ('\u04f0', '\u04f1'), ('\u04f2', '\u04f3'), ('\u04f4', '\u04f5'), ('\u04f6', '\u04f7'),
+ ('\u04f8', '\u04f9'), ('\u04fa', '\u04fb'), ('\u04fc', '\u04fd'), ('\u04fe', '\u04ff'),
+ ('\u0500', '\u0501'), ('\u0502', '\u0503'), ('\u0504', '\u0505'), ('\u0506', '\u0507'),
+ ('\u0508', '\u0509'), ('\u050a', '\u050b'), ('\u050c', '\u050d'), ('\u050e', '\u050f'),
+ ('\u0510', '\u0511'), ('\u0512', '\u0513'), ('\u0514', '\u0515'), ('\u0516', '\u0517'),
+ ('\u0518', '\u0519'), ('\u051a', '\u051b'), ('\u051c', '\u051d'), ('\u051e', '\u051f'),
+ ('\u0520', '\u0521'), ('\u0522', '\u0523'), ('\u0524', '\u0525'), ('\u0526', '\u0527'),
+ ('\u0528', '\u0529'), ('\u052a', '\u052b'), ('\u052c', '\u052d'), ('\u052e', '\u052f'),
+ ('\u0531', '\u0561'), ('\u0532', '\u0562'), ('\u0533', '\u0563'), ('\u0534', '\u0564'),
+ ('\u0535', '\u0565'), ('\u0536', '\u0566'), ('\u0537', '\u0567'), ('\u0538', '\u0568'),
+ ('\u0539', '\u0569'), ('\u053a', '\u056a'), ('\u053b', '\u056b'), ('\u053c', '\u056c'),
+ ('\u053d', '\u056d'), ('\u053e', '\u056e'), ('\u053f', '\u056f'), ('\u0540', '\u0570'),
+ ('\u0541', '\u0571'), ('\u0542', '\u0572'), ('\u0543', '\u0573'), ('\u0544', '\u0574'),
+ ('\u0545', '\u0575'), ('\u0546', '\u0576'), ('\u0547', '\u0577'), ('\u0548', '\u0578'),
+ ('\u0549', '\u0579'), ('\u054a', '\u057a'), ('\u054b', '\u057b'), ('\u054c', '\u057c'),
+ ('\u054d', '\u057d'), ('\u054e', '\u057e'), ('\u054f', '\u057f'), ('\u0550', '\u0580'),
+ ('\u0551', '\u0581'), ('\u0552', '\u0582'), ('\u0553', '\u0583'), ('\u0554', '\u0584'),
+ ('\u0555', '\u0585'), ('\u0556', '\u0586'), ('\u10a0', '\u2d00'), ('\u10a1', '\u2d01'),
+ ('\u10a2', '\u2d02'), ('\u10a3', '\u2d03'), ('\u10a4', '\u2d04'), ('\u10a5', '\u2d05'),
+ ('\u10a6', '\u2d06'), ('\u10a7', '\u2d07'), ('\u10a8', '\u2d08'), ('\u10a9', '\u2d09'),
+ ('\u10aa', '\u2d0a'), ('\u10ab', '\u2d0b'), ('\u10ac', '\u2d0c'), ('\u10ad', '\u2d0d'),
+ ('\u10ae', '\u2d0e'), ('\u10af', '\u2d0f'), ('\u10b0', '\u2d10'), ('\u10b1', '\u2d11'),
+ ('\u10b2', '\u2d12'), ('\u10b3', '\u2d13'), ('\u10b4', '\u2d14'), ('\u10b5', '\u2d15'),
+ ('\u10b6', '\u2d16'), ('\u10b7', '\u2d17'), ('\u10b8', '\u2d18'), ('\u10b9', '\u2d19'),
+ ('\u10ba', '\u2d1a'), ('\u10bb', '\u2d1b'), ('\u10bc', '\u2d1c'), ('\u10bd', '\u2d1d'),
+ ('\u10be', '\u2d1e'), ('\u10bf', '\u2d1f'), ('\u10c0', '\u2d20'), ('\u10c1', '\u2d21'),
+ ('\u10c2', '\u2d22'), ('\u10c3', '\u2d23'), ('\u10c4', '\u2d24'), ('\u10c5', '\u2d25'),
+ ('\u10c7', '\u2d27'), ('\u10cd', '\u2d2d'), ('\u1e00', '\u1e01'), ('\u1e02', '\u1e03'),
+ ('\u1e04', '\u1e05'), ('\u1e06', '\u1e07'), ('\u1e08', '\u1e09'), ('\u1e0a', '\u1e0b'),
+ ('\u1e0c', '\u1e0d'), ('\u1e0e', '\u1e0f'), ('\u1e10', '\u1e11'), ('\u1e12', '\u1e13'),
+ ('\u1e14', '\u1e15'), ('\u1e16', '\u1e17'), ('\u1e18', '\u1e19'), ('\u1e1a', '\u1e1b'),
+ ('\u1e1c', '\u1e1d'), ('\u1e1e', '\u1e1f'), ('\u1e20', '\u1e21'), ('\u1e22', '\u1e23'),
+ ('\u1e24', '\u1e25'), ('\u1e26', '\u1e27'), ('\u1e28', '\u1e29'), ('\u1e2a', '\u1e2b'),
+ ('\u1e2c', '\u1e2d'), ('\u1e2e', '\u1e2f'), ('\u1e30', '\u1e31'), ('\u1e32', '\u1e33'),
+ ('\u1e34', '\u1e35'), ('\u1e36', '\u1e37'), ('\u1e38', '\u1e39'), ('\u1e3a', '\u1e3b'),
+ ('\u1e3c', '\u1e3d'), ('\u1e3e', '\u1e3f'), ('\u1e40', '\u1e41'), ('\u1e42', '\u1e43'),
+ ('\u1e44', '\u1e45'), ('\u1e46', '\u1e47'), ('\u1e48', '\u1e49'), ('\u1e4a', '\u1e4b'),
+ ('\u1e4c', '\u1e4d'), ('\u1e4e', '\u1e4f'), ('\u1e50', '\u1e51'), ('\u1e52', '\u1e53'),
+ ('\u1e54', '\u1e55'), ('\u1e56', '\u1e57'), ('\u1e58', '\u1e59'), ('\u1e5a', '\u1e5b'),
+ ('\u1e5c', '\u1e5d'), ('\u1e5e', '\u1e5f'), ('\u1e60', '\u1e61'), ('\u1e62', '\u1e63'),
+ ('\u1e64', '\u1e65'), ('\u1e66', '\u1e67'), ('\u1e68', '\u1e69'), ('\u1e6a', '\u1e6b'),
+ ('\u1e6c', '\u1e6d'), ('\u1e6e', '\u1e6f'), ('\u1e70', '\u1e71'), ('\u1e72', '\u1e73'),
+ ('\u1e74', '\u1e75'), ('\u1e76', '\u1e77'), ('\u1e78', '\u1e79'), ('\u1e7a', '\u1e7b'),
+ ('\u1e7c', '\u1e7d'), ('\u1e7e', '\u1e7f'), ('\u1e80', '\u1e81'), ('\u1e82', '\u1e83'),
+ ('\u1e84', '\u1e85'), ('\u1e86', '\u1e87'), ('\u1e88', '\u1e89'), ('\u1e8a', '\u1e8b'),
+ ('\u1e8c', '\u1e8d'), ('\u1e8e', '\u1e8f'), ('\u1e90', '\u1e91'), ('\u1e92', '\u1e93'),
+ ('\u1e94', '\u1e95'), ('\u1e9e', '\xdf'), ('\u1ea0', '\u1ea1'), ('\u1ea2', '\u1ea3'),
+ ('\u1ea4', '\u1ea5'), ('\u1ea6', '\u1ea7'), ('\u1ea8', '\u1ea9'), ('\u1eaa', '\u1eab'),
+ ('\u1eac', '\u1ead'), ('\u1eae', '\u1eaf'), ('\u1eb0', '\u1eb1'), ('\u1eb2', '\u1eb3'),
+ ('\u1eb4', '\u1eb5'), ('\u1eb6', '\u1eb7'), ('\u1eb8', '\u1eb9'), ('\u1eba', '\u1ebb'),
+ ('\u1ebc', '\u1ebd'), ('\u1ebe', '\u1ebf'), ('\u1ec0', '\u1ec1'), ('\u1ec2', '\u1ec3'),
+ ('\u1ec4', '\u1ec5'), ('\u1ec6', '\u1ec7'), ('\u1ec8', '\u1ec9'), ('\u1eca', '\u1ecb'),
+ ('\u1ecc', '\u1ecd'), ('\u1ece', '\u1ecf'), ('\u1ed0', '\u1ed1'), ('\u1ed2', '\u1ed3'),
+ ('\u1ed4', '\u1ed5'), ('\u1ed6', '\u1ed7'), ('\u1ed8', '\u1ed9'), ('\u1eda', '\u1edb'),
+ ('\u1edc', '\u1edd'), ('\u1ede', '\u1edf'), ('\u1ee0', '\u1ee1'), ('\u1ee2', '\u1ee3'),
+ ('\u1ee4', '\u1ee5'), ('\u1ee6', '\u1ee7'), ('\u1ee8', '\u1ee9'), ('\u1eea', '\u1eeb'),
+ ('\u1eec', '\u1eed'), ('\u1eee', '\u1eef'), ('\u1ef0', '\u1ef1'), ('\u1ef2', '\u1ef3'),
+ ('\u1ef4', '\u1ef5'), ('\u1ef6', '\u1ef7'), ('\u1ef8', '\u1ef9'), ('\u1efa', '\u1efb'),
+ ('\u1efc', '\u1efd'), ('\u1efe', '\u1eff'), ('\u1f08', '\u1f00'), ('\u1f09', '\u1f01'),
+ ('\u1f0a', '\u1f02'), ('\u1f0b', '\u1f03'), ('\u1f0c', '\u1f04'), ('\u1f0d', '\u1f05'),
+ ('\u1f0e', '\u1f06'), ('\u1f0f', '\u1f07'), ('\u1f18', '\u1f10'), ('\u1f19', '\u1f11'),
+ ('\u1f1a', '\u1f12'), ('\u1f1b', '\u1f13'), ('\u1f1c', '\u1f14'), ('\u1f1d', '\u1f15'),
+ ('\u1f28', '\u1f20'), ('\u1f29', '\u1f21'), ('\u1f2a', '\u1f22'), ('\u1f2b', '\u1f23'),
+ ('\u1f2c', '\u1f24'), ('\u1f2d', '\u1f25'), ('\u1f2e', '\u1f26'), ('\u1f2f', '\u1f27'),
+ ('\u1f38', '\u1f30'), ('\u1f39', '\u1f31'), ('\u1f3a', '\u1f32'), ('\u1f3b', '\u1f33'),
+ ('\u1f3c', '\u1f34'), ('\u1f3d', '\u1f35'), ('\u1f3e', '\u1f36'), ('\u1f3f', '\u1f37'),
+ ('\u1f48', '\u1f40'), ('\u1f49', '\u1f41'), ('\u1f4a', '\u1f42'), ('\u1f4b', '\u1f43'),
+ ('\u1f4c', '\u1f44'), ('\u1f4d', '\u1f45'), ('\u1f59', '\u1f51'), ('\u1f5b', '\u1f53'),
+ ('\u1f5d', '\u1f55'), ('\u1f5f', '\u1f57'), ('\u1f68', '\u1f60'), ('\u1f69', '\u1f61'),
+ ('\u1f6a', '\u1f62'), ('\u1f6b', '\u1f63'), ('\u1f6c', '\u1f64'), ('\u1f6d', '\u1f65'),
+ ('\u1f6e', '\u1f66'), ('\u1f6f', '\u1f67'), ('\u1fb8', '\u1fb0'), ('\u1fb9', '\u1fb1'),
+ ('\u1fba', '\u1f70'), ('\u1fbb', '\u1f71'), ('\u1fc8', '\u1f72'), ('\u1fc9', '\u1f73'),
+ ('\u1fca', '\u1f74'), ('\u1fcb', '\u1f75'), ('\u1fd8', '\u1fd0'), ('\u1fd9', '\u1fd1'),
+ ('\u1fda', '\u1f76'), ('\u1fdb', '\u1f77'), ('\u1fe8', '\u1fe0'), ('\u1fe9', '\u1fe1'),
+ ('\u1fea', '\u1f7a'), ('\u1feb', '\u1f7b'), ('\u1fec', '\u1fe5'), ('\u1ff8', '\u1f78'),
+ ('\u1ff9', '\u1f79'), ('\u1ffa', '\u1f7c'), ('\u1ffb', '\u1f7d'), ('\u2126', '\u03c9'),
+ ('\u212a', '\x6b'), ('\u212b', '\xe5'), ('\u2132', '\u214e'), ('\u2183', '\u2184'),
+ ('\u2c00', '\u2c30'), ('\u2c01', '\u2c31'), ('\u2c02', '\u2c32'), ('\u2c03', '\u2c33'),
+ ('\u2c04', '\u2c34'), ('\u2c05', '\u2c35'), ('\u2c06', '\u2c36'), ('\u2c07', '\u2c37'),
+ ('\u2c08', '\u2c38'), ('\u2c09', '\u2c39'), ('\u2c0a', '\u2c3a'), ('\u2c0b', '\u2c3b'),
+ ('\u2c0c', '\u2c3c'), ('\u2c0d', '\u2c3d'), ('\u2c0e', '\u2c3e'), ('\u2c0f', '\u2c3f'),
+ ('\u2c10', '\u2c40'), ('\u2c11', '\u2c41'), ('\u2c12', '\u2c42'), ('\u2c13', '\u2c43'),
+ ('\u2c14', '\u2c44'), ('\u2c15', '\u2c45'), ('\u2c16', '\u2c46'), ('\u2c17', '\u2c47'),
+ ('\u2c18', '\u2c48'), ('\u2c19', '\u2c49'), ('\u2c1a', '\u2c4a'), ('\u2c1b', '\u2c4b'),
+ ('\u2c1c', '\u2c4c'), ('\u2c1d', '\u2c4d'), ('\u2c1e', '\u2c4e'), ('\u2c1f', '\u2c4f'),
+ ('\u2c20', '\u2c50'), ('\u2c21', '\u2c51'), ('\u2c22', '\u2c52'), ('\u2c23', '\u2c53'),
+ ('\u2c24', '\u2c54'), ('\u2c25', '\u2c55'), ('\u2c26', '\u2c56'), ('\u2c27', '\u2c57'),
+ ('\u2c28', '\u2c58'), ('\u2c29', '\u2c59'), ('\u2c2a', '\u2c5a'), ('\u2c2b', '\u2c5b'),
+ ('\u2c2c', '\u2c5c'), ('\u2c2d', '\u2c5d'), ('\u2c2e', '\u2c5e'), ('\u2c60', '\u2c61'),
+ ('\u2c62', '\u026b'), ('\u2c63', '\u1d7d'), ('\u2c64', '\u027d'), ('\u2c67', '\u2c68'),
+ ('\u2c69', '\u2c6a'), ('\u2c6b', '\u2c6c'), ('\u2c6d', '\u0251'), ('\u2c6e', '\u0271'),
+ ('\u2c6f', '\u0250'), ('\u2c70', '\u0252'), ('\u2c72', '\u2c73'), ('\u2c75', '\u2c76'),
+ ('\u2c7e', '\u023f'), ('\u2c7f', '\u0240'), ('\u2c80', '\u2c81'), ('\u2c82', '\u2c83'),
+ ('\u2c84', '\u2c85'), ('\u2c86', '\u2c87'), ('\u2c88', '\u2c89'), ('\u2c8a', '\u2c8b'),
+ ('\u2c8c', '\u2c8d'), ('\u2c8e', '\u2c8f'), ('\u2c90', '\u2c91'), ('\u2c92', '\u2c93'),
+ ('\u2c94', '\u2c95'), ('\u2c96', '\u2c97'), ('\u2c98', '\u2c99'), ('\u2c9a', '\u2c9b'),
+ ('\u2c9c', '\u2c9d'), ('\u2c9e', '\u2c9f'), ('\u2ca0', '\u2ca1'), ('\u2ca2', '\u2ca3'),
+ ('\u2ca4', '\u2ca5'), ('\u2ca6', '\u2ca7'), ('\u2ca8', '\u2ca9'), ('\u2caa', '\u2cab'),
+ ('\u2cac', '\u2cad'), ('\u2cae', '\u2caf'), ('\u2cb0', '\u2cb1'), ('\u2cb2', '\u2cb3'),
+ ('\u2cb4', '\u2cb5'), ('\u2cb6', '\u2cb7'), ('\u2cb8', '\u2cb9'), ('\u2cba', '\u2cbb'),
+ ('\u2cbc', '\u2cbd'), ('\u2cbe', '\u2cbf'), ('\u2cc0', '\u2cc1'), ('\u2cc2', '\u2cc3'),
+ ('\u2cc4', '\u2cc5'), ('\u2cc6', '\u2cc7'), ('\u2cc8', '\u2cc9'), ('\u2cca', '\u2ccb'),
+ ('\u2ccc', '\u2ccd'), ('\u2cce', '\u2ccf'), ('\u2cd0', '\u2cd1'), ('\u2cd2', '\u2cd3'),
+ ('\u2cd4', '\u2cd5'), ('\u2cd6', '\u2cd7'), ('\u2cd8', '\u2cd9'), ('\u2cda', '\u2cdb'),
+ ('\u2cdc', '\u2cdd'), ('\u2cde', '\u2cdf'), ('\u2ce0', '\u2ce1'), ('\u2ce2', '\u2ce3'),
+ ('\u2ceb', '\u2cec'), ('\u2ced', '\u2cee'), ('\u2cf2', '\u2cf3'), ('\ua640', '\ua641'),
+ ('\ua642', '\ua643'), ('\ua644', '\ua645'), ('\ua646', '\ua647'), ('\ua648', '\ua649'),
+ ('\ua64a', '\ua64b'), ('\ua64c', '\ua64d'), ('\ua64e', '\ua64f'), ('\ua650', '\ua651'),
+ ('\ua652', '\ua653'), ('\ua654', '\ua655'), ('\ua656', '\ua657'), ('\ua658', '\ua659'),
+ ('\ua65a', '\ua65b'), ('\ua65c', '\ua65d'), ('\ua65e', '\ua65f'), ('\ua660', '\ua661'),
+ ('\ua662', '\ua663'), ('\ua664', '\ua665'), ('\ua666', '\ua667'), ('\ua668', '\ua669'),
+ ('\ua66a', '\ua66b'), ('\ua66c', '\ua66d'), ('\ua680', '\ua681'), ('\ua682', '\ua683'),
+ ('\ua684', '\ua685'), ('\ua686', '\ua687'), ('\ua688', '\ua689'), ('\ua68a', '\ua68b'),
+ ('\ua68c', '\ua68d'), ('\ua68e', '\ua68f'), ('\ua690', '\ua691'), ('\ua692', '\ua693'),
+ ('\ua694', '\ua695'), ('\ua696', '\ua697'), ('\ua698', '\ua699'), ('\ua69a', '\ua69b'),
+ ('\ua722', '\ua723'), ('\ua724', '\ua725'), ('\ua726', '\ua727'), ('\ua728', '\ua729'),
+ ('\ua72a', '\ua72b'), ('\ua72c', '\ua72d'), ('\ua72e', '\ua72f'), ('\ua732', '\ua733'),
+ ('\ua734', '\ua735'), ('\ua736', '\ua737'), ('\ua738', '\ua739'), ('\ua73a', '\ua73b'),
+ ('\ua73c', '\ua73d'), ('\ua73e', '\ua73f'), ('\ua740', '\ua741'), ('\ua742', '\ua743'),
+ ('\ua744', '\ua745'), ('\ua746', '\ua747'), ('\ua748', '\ua749'), ('\ua74a', '\ua74b'),
+ ('\ua74c', '\ua74d'), ('\ua74e', '\ua74f'), ('\ua750', '\ua751'), ('\ua752', '\ua753'),
+ ('\ua754', '\ua755'), ('\ua756', '\ua757'), ('\ua758', '\ua759'), ('\ua75a', '\ua75b'),
+ ('\ua75c', '\ua75d'), ('\ua75e', '\ua75f'), ('\ua760', '\ua761'), ('\ua762', '\ua763'),
+ ('\ua764', '\ua765'), ('\ua766', '\ua767'), ('\ua768', '\ua769'), ('\ua76a', '\ua76b'),
+ ('\ua76c', '\ua76d'), ('\ua76e', '\ua76f'), ('\ua779', '\ua77a'), ('\ua77b', '\ua77c'),
+ ('\ua77d', '\u1d79'), ('\ua77e', '\ua77f'), ('\ua780', '\ua781'), ('\ua782', '\ua783'),
+ ('\ua784', '\ua785'), ('\ua786', '\ua787'), ('\ua78b', '\ua78c'), ('\ua78d', '\u0265'),
+ ('\ua790', '\ua791'), ('\ua792', '\ua793'), ('\ua796', '\ua797'), ('\ua798', '\ua799'),
+ ('\ua79a', '\ua79b'), ('\ua79c', '\ua79d'), ('\ua79e', '\ua79f'), ('\ua7a0', '\ua7a1'),
+ ('\ua7a2', '\ua7a3'), ('\ua7a4', '\ua7a5'), ('\ua7a6', '\ua7a7'), ('\ua7a8', '\ua7a9'),
+ ('\ua7aa', '\u0266'), ('\ua7ab', '\u025c'), ('\ua7ac', '\u0261'), ('\ua7ad', '\u026c'),
+ ('\ua7b0', '\u029e'), ('\ua7b1', '\u0287'), ('\uff21', '\uff41'), ('\uff22', '\uff42'),
+ ('\uff23', '\uff43'), ('\uff24', '\uff44'), ('\uff25', '\uff45'), ('\uff26', '\uff46'),
+ ('\uff27', '\uff47'), ('\uff28', '\uff48'), ('\uff29', '\uff49'), ('\uff2a', '\uff4a'),
+ ('\uff2b', '\uff4b'), ('\uff2c', '\uff4c'), ('\uff2d', '\uff4d'), ('\uff2e', '\uff4e'),
+ ('\uff2f', '\uff4f'), ('\uff30', '\uff50'), ('\uff31', '\uff51'), ('\uff32', '\uff52'),
+ ('\uff33', '\uff53'), ('\uff34', '\uff54'), ('\uff35', '\uff55'), ('\uff36', '\uff56'),
+ ('\uff37', '\uff57'), ('\uff38', '\uff58'), ('\uff39', '\uff59'), ('\uff3a', '\uff5a'),
+ ('\U00010400', '\U00010428'), ('\U00010401', '\U00010429'), ('\U00010402', '\U0001042a'),
+ ('\U00010403', '\U0001042b'), ('\U00010404', '\U0001042c'), ('\U00010405', '\U0001042d'),
+ ('\U00010406', '\U0001042e'), ('\U00010407', '\U0001042f'), ('\U00010408', '\U00010430'),
+ ('\U00010409', '\U00010431'), ('\U0001040a', '\U00010432'), ('\U0001040b', '\U00010433'),
+ ('\U0001040c', '\U00010434'), ('\U0001040d', '\U00010435'), ('\U0001040e', '\U00010436'),
+ ('\U0001040f', '\U00010437'), ('\U00010410', '\U00010438'), ('\U00010411', '\U00010439'),
+ ('\U00010412', '\U0001043a'), ('\U00010413', '\U0001043b'), ('\U00010414', '\U0001043c'),
+ ('\U00010415', '\U0001043d'), ('\U00010416', '\U0001043e'), ('\U00010417', '\U0001043f'),
+ ('\U00010418', '\U00010440'), ('\U00010419', '\U00010441'), ('\U0001041a', '\U00010442'),
+ ('\U0001041b', '\U00010443'), ('\U0001041c', '\U00010444'), ('\U0001041d', '\U00010445'),
+ ('\U0001041e', '\U00010446'), ('\U0001041f', '\U00010447'), ('\U00010420', '\U00010448'),
+ ('\U00010421', '\U00010449'), ('\U00010422', '\U0001044a'), ('\U00010423', '\U0001044b'),
+ ('\U00010424', '\U0001044c'), ('\U00010425', '\U0001044d'), ('\U00010426', '\U0001044e'),
+ ('\U00010427', '\U0001044f'), ('\U000118a0', '\U000118c0'), ('\U000118a1', '\U000118c1'),
+ ('\U000118a2', '\U000118c2'), ('\U000118a3', '\U000118c3'), ('\U000118a4', '\U000118c4'),
+ ('\U000118a5', '\U000118c5'), ('\U000118a6', '\U000118c6'), ('\U000118a7', '\U000118c7'),
+ ('\U000118a8', '\U000118c8'), ('\U000118a9', '\U000118c9'), ('\U000118aa', '\U000118ca'),
+ ('\U000118ab', '\U000118cb'), ('\U000118ac', '\U000118cc'), ('\U000118ad', '\U000118cd'),
+ ('\U000118ae', '\U000118ce'), ('\U000118af', '\U000118cf'), ('\U000118b0', '\U000118d0'),
+ ('\U000118b1', '\U000118d1'), ('\U000118b2', '\U000118d2'), ('\U000118b3', '\U000118d3'),
+ ('\U000118b4', '\U000118d4'), ('\U000118b5', '\U000118d5'), ('\U000118b6', '\U000118d6'),
+ ('\U000118b7', '\U000118d7'), ('\U000118b8', '\U000118d8'), ('\U000118b9', '\U000118d9'),
+ ('\U000118ba', '\U000118da'), ('\U000118bb', '\U000118db'), ('\U000118bc', '\U000118dc'),
+ ('\U000118bd', '\U000118dd'), ('\U000118be', '\U000118de'), ('\U000118bf', '\U000118df')
+ ];
+
+ static LlLu_table: &'static [(char, char)] = &[
+ ('\x61', '\x41'), ('\x62', '\x42'), ('\x63', '\x43'), ('\x64', '\x44'), ('\x65', '\x45'),
+ ('\x66', '\x46'), ('\x67', '\x47'), ('\x68', '\x48'), ('\x69', '\x49'), ('\x6a', '\x4a'),
+ ('\x6b', '\x4b'), ('\x6c', '\x4c'), ('\x6d', '\x4d'), ('\x6e', '\x4e'), ('\x6f', '\x4f'),
+ ('\x70', '\x50'), ('\x71', '\x51'), ('\x72', '\x52'), ('\x73', '\x53'), ('\x74', '\x54'),
+ ('\x75', '\x55'), ('\x76', '\x56'), ('\x77', '\x57'), ('\x78', '\x58'), ('\x79', '\x59'),
+ ('\x7a', '\x5a'), ('\xb5', '\u039c'), ('\xe0', '\xc0'), ('\xe1', '\xc1'), ('\xe2', '\xc2'),
+ ('\xe3', '\xc3'), ('\xe4', '\xc4'), ('\xe5', '\xc5'), ('\xe6', '\xc6'), ('\xe7', '\xc7'),
+ ('\xe8', '\xc8'), ('\xe9', '\xc9'), ('\xea', '\xca'), ('\xeb', '\xcb'), ('\xec', '\xcc'),
+ ('\xed', '\xcd'), ('\xee', '\xce'), ('\xef', '\xcf'), ('\xf0', '\xd0'), ('\xf1', '\xd1'),
+ ('\xf2', '\xd2'), ('\xf3', '\xd3'), ('\xf4', '\xd4'), ('\xf5', '\xd5'), ('\xf6', '\xd6'),
+ ('\xf8', '\xd8'), ('\xf9', '\xd9'), ('\xfa', '\xda'), ('\xfb', '\xdb'), ('\xfc', '\xdc'),
+ ('\xfd', '\xdd'), ('\xfe', '\xde'), ('\xff', '\u0178'), ('\u0101', '\u0100'), ('\u0103',
+ '\u0102'), ('\u0105', '\u0104'), ('\u0107', '\u0106'), ('\u0109', '\u0108'), ('\u010b',
+ '\u010a'), ('\u010d', '\u010c'), ('\u010f', '\u010e'), ('\u0111', '\u0110'), ('\u0113',
+ '\u0112'), ('\u0115', '\u0114'), ('\u0117', '\u0116'), ('\u0119', '\u0118'), ('\u011b',
+ '\u011a'), ('\u011d', '\u011c'), ('\u011f', '\u011e'), ('\u0121', '\u0120'), ('\u0123',
+ '\u0122'), ('\u0125', '\u0124'), ('\u0127', '\u0126'), ('\u0129', '\u0128'), ('\u012b',
+ '\u012a'), ('\u012d', '\u012c'), ('\u012f', '\u012e'), ('\u0131', '\x49'), ('\u0133',
+ '\u0132'), ('\u0135', '\u0134'), ('\u0137', '\u0136'), ('\u013a', '\u0139'), ('\u013c',
+ '\u013b'), ('\u013e', '\u013d'), ('\u0140', '\u013f'), ('\u0142', '\u0141'), ('\u0144',
+ '\u0143'), ('\u0146', '\u0145'), ('\u0148', '\u0147'), ('\u014b', '\u014a'), ('\u014d',
+ '\u014c'), ('\u014f', '\u014e'), ('\u0151', '\u0150'), ('\u0153', '\u0152'), ('\u0155',
+ '\u0154'), ('\u0157', '\u0156'), ('\u0159', '\u0158'), ('\u015b', '\u015a'), ('\u015d',
+ '\u015c'), ('\u015f', '\u015e'), ('\u0161', '\u0160'), ('\u0163', '\u0162'), ('\u0165',
+ '\u0164'), ('\u0167', '\u0166'), ('\u0169', '\u0168'), ('\u016b', '\u016a'), ('\u016d',
+ '\u016c'), ('\u016f', '\u016e'), ('\u0171', '\u0170'), ('\u0173', '\u0172'), ('\u0175',
+ '\u0174'), ('\u0177', '\u0176'), ('\u017a', '\u0179'), ('\u017c', '\u017b'), ('\u017e',
+ '\u017d'), ('\u017f', '\x53'), ('\u0180', '\u0243'), ('\u0183', '\u0182'), ('\u0185',
+ '\u0184'), ('\u0188', '\u0187'), ('\u018c', '\u018b'), ('\u0192', '\u0191'), ('\u0195',
+ '\u01f6'), ('\u0199', '\u0198'), ('\u019a', '\u023d'), ('\u019e', '\u0220'), ('\u01a1',
+ '\u01a0'), ('\u01a3', '\u01a2'), ('\u01a5', '\u01a4'), ('\u01a8', '\u01a7'), ('\u01ad',
+ '\u01ac'), ('\u01b0', '\u01af'), ('\u01b4', '\u01b3'), ('\u01b6', '\u01b5'), ('\u01b9',
+ '\u01b8'), ('\u01bd', '\u01bc'), ('\u01bf', '\u01f7'), ('\u01c6', '\u01c4'), ('\u01c9',
+ '\u01c7'), ('\u01cc', '\u01ca'), ('\u01ce', '\u01cd'), ('\u01d0', '\u01cf'), ('\u01d2',
+ '\u01d1'), ('\u01d4', '\u01d3'), ('\u01d6', '\u01d5'), ('\u01d8', '\u01d7'), ('\u01da',
+ '\u01d9'), ('\u01dc', '\u01db'), ('\u01dd', '\u018e'), ('\u01df', '\u01de'), ('\u01e1',
+ '\u01e0'), ('\u01e3', '\u01e2'), ('\u01e5', '\u01e4'), ('\u01e7', '\u01e6'), ('\u01e9',
+ '\u01e8'), ('\u01eb', '\u01ea'), ('\u01ed', '\u01ec'), ('\u01ef', '\u01ee'), ('\u01f3',
+ '\u01f1'), ('\u01f5', '\u01f4'), ('\u01f9', '\u01f8'), ('\u01fb', '\u01fa'), ('\u01fd',
+ '\u01fc'), ('\u01ff', '\u01fe'), ('\u0201', '\u0200'), ('\u0203', '\u0202'), ('\u0205',
+ '\u0204'), ('\u0207', '\u0206'), ('\u0209', '\u0208'), ('\u020b', '\u020a'), ('\u020d',
+ '\u020c'), ('\u020f', '\u020e'), ('\u0211', '\u0210'), ('\u0213', '\u0212'), ('\u0215',
+ '\u0214'), ('\u0217', '\u0216'), ('\u0219', '\u0218'), ('\u021b', '\u021a'), ('\u021d',
+ '\u021c'), ('\u021f', '\u021e'), ('\u0223', '\u0222'), ('\u0225', '\u0224'), ('\u0227',
+ '\u0226'), ('\u0229', '\u0228'), ('\u022b', '\u022a'), ('\u022d', '\u022c'), ('\u022f',
+ '\u022e'), ('\u0231', '\u0230'), ('\u0233', '\u0232'), ('\u023c', '\u023b'), ('\u023f',
+ '\u2c7e'), ('\u0240', '\u2c7f'), ('\u0242', '\u0241'), ('\u0247', '\u0246'), ('\u0249',
+ '\u0248'), ('\u024b', '\u024a'), ('\u024d', '\u024c'), ('\u024f', '\u024e'), ('\u0250',
+ '\u2c6f'), ('\u0251', '\u2c6d'), ('\u0252', '\u2c70'), ('\u0253', '\u0181'), ('\u0254',
+ '\u0186'), ('\u0256', '\u0189'), ('\u0257', '\u018a'), ('\u0259', '\u018f'), ('\u025b',
+ '\u0190'), ('\u025c', '\ua7ab'), ('\u0260', '\u0193'), ('\u0261', '\ua7ac'), ('\u0263',
+ '\u0194'), ('\u0265', '\ua78d'), ('\u0266', '\ua7aa'), ('\u0268', '\u0197'), ('\u0269',
+ '\u0196'), ('\u026b', '\u2c62'), ('\u026c', '\ua7ad'), ('\u026f', '\u019c'), ('\u0271',
+ '\u2c6e'), ('\u0272', '\u019d'), ('\u0275', '\u019f'), ('\u027d', '\u2c64'), ('\u0280',
+ '\u01a6'), ('\u0283', '\u01a9'), ('\u0287', '\ua7b1'), ('\u0288', '\u01ae'), ('\u0289',
+ '\u0244'), ('\u028a', '\u01b1'), ('\u028b', '\u01b2'), ('\u028c', '\u0245'), ('\u0292',
+ '\u01b7'), ('\u029e', '\ua7b0'), ('\u0371', '\u0370'), ('\u0373', '\u0372'), ('\u0377',
+ '\u0376'), ('\u037b', '\u03fd'), ('\u037c', '\u03fe'), ('\u037d', '\u03ff'), ('\u03ac',
+ '\u0386'), ('\u03ad', '\u0388'), ('\u03ae', '\u0389'), ('\u03af', '\u038a'), ('\u03b1',
+ '\u0391'), ('\u03b2', '\u0392'), ('\u03b3', '\u0393'), ('\u03b4', '\u0394'), ('\u03b5',
+ '\u0395'), ('\u03b6', '\u0396'), ('\u03b7', '\u0397'), ('\u03b8', '\u0398'), ('\u03b9',
+ '\u0399'), ('\u03ba', '\u039a'), ('\u03bb', '\u039b'), ('\u03bc', '\u039c'), ('\u03bd',
+ '\u039d'), ('\u03be', '\u039e'), ('\u03bf', '\u039f'), ('\u03c0', '\u03a0'), ('\u03c1',
+ '\u03a1'), ('\u03c2', '\u03a3'), ('\u03c3', '\u03a3'), ('\u03c4', '\u03a4'), ('\u03c5',
+ '\u03a5'), ('\u03c6', '\u03a6'), ('\u03c7', '\u03a7'), ('\u03c8', '\u03a8'), ('\u03c9',
+ '\u03a9'), ('\u03ca', '\u03aa'), ('\u03cb', '\u03ab'), ('\u03cc', '\u038c'), ('\u03cd',
+ '\u038e'), ('\u03ce', '\u038f'), ('\u03d0', '\u0392'), ('\u03d1', '\u0398'), ('\u03d5',
+ '\u03a6'), ('\u03d6', '\u03a0'), ('\u03d7', '\u03cf'), ('\u03d9', '\u03d8'), ('\u03db',
+ '\u03da'), ('\u03dd', '\u03dc'), ('\u03df', '\u03de'), ('\u03e1', '\u03e0'), ('\u03e3',
+ '\u03e2'), ('\u03e5', '\u03e4'), ('\u03e7', '\u03e6'), ('\u03e9', '\u03e8'), ('\u03eb',
+ '\u03ea'), ('\u03ed', '\u03ec'), ('\u03ef', '\u03ee'), ('\u03f0', '\u039a'), ('\u03f1',
+ '\u03a1'), ('\u03f2', '\u03f9'), ('\u03f3', '\u037f'), ('\u03f5', '\u0395'), ('\u03f8',
+ '\u03f7'), ('\u03fb', '\u03fa'), ('\u0430', '\u0410'), ('\u0431', '\u0411'), ('\u0432',
+ '\u0412'), ('\u0433', '\u0413'), ('\u0434', '\u0414'), ('\u0435', '\u0415'), ('\u0436',
+ '\u0416'), ('\u0437', '\u0417'), ('\u0438', '\u0418'), ('\u0439', '\u0419'), ('\u043a',
+ '\u041a'), ('\u043b', '\u041b'), ('\u043c', '\u041c'), ('\u043d', '\u041d'), ('\u043e',
+ '\u041e'), ('\u043f', '\u041f'), ('\u0440', '\u0420'), ('\u0441', '\u0421'), ('\u0442',
+ '\u0422'), ('\u0443', '\u0423'), ('\u0444', '\u0424'), ('\u0445', '\u0425'), ('\u0446',
+ '\u0426'), ('\u0447', '\u0427'), ('\u0448', '\u0428'), ('\u0449', '\u0429'), ('\u044a',
+ '\u042a'), ('\u044b', '\u042b'), ('\u044c', '\u042c'), ('\u044d', '\u042d'), ('\u044e',
+ '\u042e'), ('\u044f', '\u042f'), ('\u0450', '\u0400'), ('\u0451', '\u0401'), ('\u0452',
+ '\u0402'), ('\u0453', '\u0403'), ('\u0454', '\u0404'), ('\u0455', '\u0405'), ('\u0456',
+ '\u0406'), ('\u0457', '\u0407'), ('\u0458', '\u0408'), ('\u0459', '\u0409'), ('\u045a',
+ '\u040a'), ('\u045b', '\u040b'), ('\u045c', '\u040c'), ('\u045d', '\u040d'), ('\u045e',
+ '\u040e'), ('\u045f', '\u040f'), ('\u0461', '\u0460'), ('\u0463', '\u0462'), ('\u0465',
+ '\u0464'), ('\u0467', '\u0466'), ('\u0469', '\u0468'), ('\u046b', '\u046a'), ('\u046d',
+ '\u046c'), ('\u046f', '\u046e'), ('\u0471', '\u0470'), ('\u0473', '\u0472'), ('\u0475',
+ '\u0474'), ('\u0477', '\u0476'), ('\u0479', '\u0478'), ('\u047b', '\u047a'), ('\u047d',
+ '\u047c'), ('\u047f', '\u047e'), ('\u0481', '\u0480'), ('\u048b', '\u048a'), ('\u048d',
+ '\u048c'), ('\u048f', '\u048e'), ('\u0491', '\u0490'), ('\u0493', '\u0492'), ('\u0495',
+ '\u0494'), ('\u0497', '\u0496'), ('\u0499', '\u0498'), ('\u049b', '\u049a'), ('\u049d',
+ '\u049c'), ('\u049f', '\u049e'), ('\u04a1', '\u04a0'), ('\u04a3', '\u04a2'), ('\u04a5',
+ '\u04a4'), ('\u04a7', '\u04a6'), ('\u04a9', '\u04a8'), ('\u04ab', '\u04aa'), ('\u04ad',
+ '\u04ac'), ('\u04af', '\u04ae'), ('\u04b1', '\u04b0'), ('\u04b3', '\u04b2'), ('\u04b5',
+ '\u04b4'), ('\u04b7', '\u04b6'), ('\u04b9', '\u04b8'), ('\u04bb', '\u04ba'), ('\u04bd',
+ '\u04bc'), ('\u04bf', '\u04be'), ('\u04c2', '\u04c1'), ('\u04c4', '\u04c3'), ('\u04c6',
+ '\u04c5'), ('\u04c8', '\u04c7'), ('\u04ca', '\u04c9'), ('\u04cc', '\u04cb'), ('\u04ce',
+ '\u04cd'), ('\u04cf', '\u04c0'), ('\u04d1', '\u04d0'), ('\u04d3', '\u04d2'), ('\u04d5',
+ '\u04d4'), ('\u04d7', '\u04d6'), ('\u04d9', '\u04d8'), ('\u04db', '\u04da'), ('\u04dd',
+ '\u04dc'), ('\u04df', '\u04de'), ('\u04e1', '\u04e0'), ('\u04e3', '\u04e2'), ('\u04e5',
+ '\u04e4'), ('\u04e7', '\u04e6'), ('\u04e9', '\u04e8'), ('\u04eb', '\u04ea'), ('\u04ed',
+ '\u04ec'), ('\u04ef', '\u04ee'), ('\u04f1', '\u04f0'), ('\u04f3', '\u04f2'), ('\u04f5',
+ '\u04f4'), ('\u04f7', '\u04f6'), ('\u04f9', '\u04f8'), ('\u04fb', '\u04fa'), ('\u04fd',
+ '\u04fc'), ('\u04ff', '\u04fe'), ('\u0501', '\u0500'), ('\u0503', '\u0502'), ('\u0505',
+ '\u0504'), ('\u0507', '\u0506'), ('\u0509', '\u0508'), ('\u050b', '\u050a'), ('\u050d',
+ '\u050c'), ('\u050f', '\u050e'), ('\u0511', '\u0510'), ('\u0513', '\u0512'), ('\u0515',
+ '\u0514'), ('\u0517', '\u0516'), ('\u0519', '\u0518'), ('\u051b', '\u051a'), ('\u051d',
+ '\u051c'), ('\u051f', '\u051e'), ('\u0521', '\u0520'), ('\u0523', '\u0522'), ('\u0525',
+ '\u0524'), ('\u0527', '\u0526'), ('\u0529', '\u0528'), ('\u052b', '\u052a'), ('\u052d',
+ '\u052c'), ('\u052f', '\u052e'), ('\u0561', '\u0531'), ('\u0562', '\u0532'), ('\u0563',
+ '\u0533'), ('\u0564', '\u0534'), ('\u0565', '\u0535'), ('\u0566', '\u0536'), ('\u0567',
+ '\u0537'), ('\u0568', '\u0538'), ('\u0569', '\u0539'), ('\u056a', '\u053a'), ('\u056b',
+ '\u053b'), ('\u056c', '\u053c'), ('\u056d', '\u053d'), ('\u056e', '\u053e'), ('\u056f',
+ '\u053f'), ('\u0570', '\u0540'), ('\u0571', '\u0541'), ('\u0572', '\u0542'), ('\u0573',
+ '\u0543'), ('\u0574', '\u0544'), ('\u0575', '\u0545'), ('\u0576', '\u0546'), ('\u0577',
+ '\u0547'), ('\u0578', '\u0548'), ('\u0579', '\u0549'), ('\u057a', '\u054a'), ('\u057b',
+ '\u054b'), ('\u057c', '\u054c'), ('\u057d', '\u054d'), ('\u057e', '\u054e'), ('\u057f',
+ '\u054f'), ('\u0580', '\u0550'), ('\u0581', '\u0551'), ('\u0582', '\u0552'), ('\u0583',
+ '\u0553'), ('\u0584', '\u0554'), ('\u0585', '\u0555'), ('\u0586', '\u0556'), ('\u1d79',
+ '\ua77d'), ('\u1d7d', '\u2c63'), ('\u1e01', '\u1e00'), ('\u1e03', '\u1e02'), ('\u1e05',
+ '\u1e04'), ('\u1e07', '\u1e06'), ('\u1e09', '\u1e08'), ('\u1e0b', '\u1e0a'), ('\u1e0d',
+ '\u1e0c'), ('\u1e0f', '\u1e0e'), ('\u1e11', '\u1e10'), ('\u1e13', '\u1e12'), ('\u1e15',
+ '\u1e14'), ('\u1e17', '\u1e16'), ('\u1e19', '\u1e18'), ('\u1e1b', '\u1e1a'), ('\u1e1d',
+ '\u1e1c'), ('\u1e1f', '\u1e1e'), ('\u1e21', '\u1e20'), ('\u1e23', '\u1e22'), ('\u1e25',
+ '\u1e24'), ('\u1e27', '\u1e26'), ('\u1e29', '\u1e28'), ('\u1e2b', '\u1e2a'), ('\u1e2d',
+ '\u1e2c'), ('\u1e2f', '\u1e2e'), ('\u1e31', '\u1e30'), ('\u1e33', '\u1e32'), ('\u1e35',
+ '\u1e34'), ('\u1e37', '\u1e36'), ('\u1e39', '\u1e38'), ('\u1e3b', '\u1e3a'), ('\u1e3d',
+ '\u1e3c'), ('\u1e3f', '\u1e3e'), ('\u1e41', '\u1e40'), ('\u1e43', '\u1e42'), ('\u1e45',
+ '\u1e44'), ('\u1e47', '\u1e46'), ('\u1e49', '\u1e48'), ('\u1e4b', '\u1e4a'), ('\u1e4d',
+ '\u1e4c'), ('\u1e4f', '\u1e4e'), ('\u1e51', '\u1e50'), ('\u1e53', '\u1e52'), ('\u1e55',
+ '\u1e54'), ('\u1e57', '\u1e56'), ('\u1e59', '\u1e58'), ('\u1e5b', '\u1e5a'), ('\u1e5d',
+ '\u1e5c'), ('\u1e5f', '\u1e5e'), ('\u1e61', '\u1e60'), ('\u1e63', '\u1e62'), ('\u1e65',
+ '\u1e64'), ('\u1e67', '\u1e66'), ('\u1e69', '\u1e68'), ('\u1e6b', '\u1e6a'), ('\u1e6d',
+ '\u1e6c'), ('\u1e6f', '\u1e6e'), ('\u1e71', '\u1e70'), ('\u1e73', '\u1e72'), ('\u1e75',
+ '\u1e74'), ('\u1e77', '\u1e76'), ('\u1e79', '\u1e78'), ('\u1e7b', '\u1e7a'), ('\u1e7d',
+ '\u1e7c'), ('\u1e7f', '\u1e7e'), ('\u1e81', '\u1e80'), ('\u1e83', '\u1e82'), ('\u1e85',
+ '\u1e84'), ('\u1e87', '\u1e86'), ('\u1e89', '\u1e88'), ('\u1e8b', '\u1e8a'), ('\u1e8d',
+ '\u1e8c'), ('\u1e8f', '\u1e8e'), ('\u1e91', '\u1e90'), ('\u1e93', '\u1e92'), ('\u1e95',
+ '\u1e94'), ('\u1e9b', '\u1e60'), ('\u1ea1', '\u1ea0'), ('\u1ea3', '\u1ea2'), ('\u1ea5',
+ '\u1ea4'), ('\u1ea7', '\u1ea6'), ('\u1ea9', '\u1ea8'), ('\u1eab', '\u1eaa'), ('\u1ead',
+ '\u1eac'), ('\u1eaf', '\u1eae'), ('\u1eb1', '\u1eb0'), ('\u1eb3', '\u1eb2'), ('\u1eb5',
+ '\u1eb4'), ('\u1eb7', '\u1eb6'), ('\u1eb9', '\u1eb8'), ('\u1ebb', '\u1eba'), ('\u1ebd',
+ '\u1ebc'), ('\u1ebf', '\u1ebe'), ('\u1ec1', '\u1ec0'), ('\u1ec3', '\u1ec2'), ('\u1ec5',
+ '\u1ec4'), ('\u1ec7', '\u1ec6'), ('\u1ec9', '\u1ec8'), ('\u1ecb', '\u1eca'), ('\u1ecd',
+ '\u1ecc'), ('\u1ecf', '\u1ece'), ('\u1ed1', '\u1ed0'), ('\u1ed3', '\u1ed2'), ('\u1ed5',
+ '\u1ed4'), ('\u1ed7', '\u1ed6'), ('\u1ed9', '\u1ed8'), ('\u1edb', '\u1eda'), ('\u1edd',
+ '\u1edc'), ('\u1edf', '\u1ede'), ('\u1ee1', '\u1ee0'), ('\u1ee3', '\u1ee2'), ('\u1ee5',
+ '\u1ee4'), ('\u1ee7', '\u1ee6'), ('\u1ee9', '\u1ee8'), ('\u1eeb', '\u1eea'), ('\u1eed',
+ '\u1eec'), ('\u1eef', '\u1eee'), ('\u1ef1', '\u1ef0'), ('\u1ef3', '\u1ef2'), ('\u1ef5',
+ '\u1ef4'), ('\u1ef7', '\u1ef6'), ('\u1ef9', '\u1ef8'), ('\u1efb', '\u1efa'), ('\u1efd',
+ '\u1efc'), ('\u1eff', '\u1efe'), ('\u1f00', '\u1f08'), ('\u1f01', '\u1f09'), ('\u1f02',
+ '\u1f0a'), ('\u1f03', '\u1f0b'), ('\u1f04', '\u1f0c'), ('\u1f05', '\u1f0d'), ('\u1f06',
+ '\u1f0e'), ('\u1f07', '\u1f0f'), ('\u1f10', '\u1f18'), ('\u1f11', '\u1f19'), ('\u1f12',
+ '\u1f1a'), ('\u1f13', '\u1f1b'), ('\u1f14', '\u1f1c'), ('\u1f15', '\u1f1d'), ('\u1f20',
+ '\u1f28'), ('\u1f21', '\u1f29'), ('\u1f22', '\u1f2a'), ('\u1f23', '\u1f2b'), ('\u1f24',
+ '\u1f2c'), ('\u1f25', '\u1f2d'), ('\u1f26', '\u1f2e'), ('\u1f27', '\u1f2f'), ('\u1f30',
+ '\u1f38'), ('\u1f31', '\u1f39'), ('\u1f32', '\u1f3a'), ('\u1f33', '\u1f3b'), ('\u1f34',
+ '\u1f3c'), ('\u1f35', '\u1f3d'), ('\u1f36', '\u1f3e'), ('\u1f37', '\u1f3f'), ('\u1f40',
+ '\u1f48'), ('\u1f41', '\u1f49'), ('\u1f42', '\u1f4a'), ('\u1f43', '\u1f4b'), ('\u1f44',
+ '\u1f4c'), ('\u1f45', '\u1f4d'), ('\u1f51', '\u1f59'), ('\u1f53', '\u1f5b'), ('\u1f55',
+ '\u1f5d'), ('\u1f57', '\u1f5f'), ('\u1f60', '\u1f68'), ('\u1f61', '\u1f69'), ('\u1f62',
+ '\u1f6a'), ('\u1f63', '\u1f6b'), ('\u1f64', '\u1f6c'), ('\u1f65', '\u1f6d'), ('\u1f66',
+ '\u1f6e'), ('\u1f67', '\u1f6f'), ('\u1f70', '\u1fba'), ('\u1f71', '\u1fbb'), ('\u1f72',
+ '\u1fc8'), ('\u1f73', '\u1fc9'), ('\u1f74', '\u1fca'), ('\u1f75', '\u1fcb'), ('\u1f76',
+ '\u1fda'), ('\u1f77', '\u1fdb'), ('\u1f78', '\u1ff8'), ('\u1f79', '\u1ff9'), ('\u1f7a',
+ '\u1fea'), ('\u1f7b', '\u1feb'), ('\u1f7c', '\u1ffa'), ('\u1f7d', '\u1ffb'), ('\u1f80',
+ '\u1f88'), ('\u1f81', '\u1f89'), ('\u1f82', '\u1f8a'), ('\u1f83', '\u1f8b'), ('\u1f84',
+ '\u1f8c'), ('\u1f85', '\u1f8d'), ('\u1f86', '\u1f8e'), ('\u1f87', '\u1f8f'), ('\u1f90',
+ '\u1f98'), ('\u1f91', '\u1f99'), ('\u1f92', '\u1f9a'), ('\u1f93', '\u1f9b'), ('\u1f94',
+ '\u1f9c'), ('\u1f95', '\u1f9d'), ('\u1f96', '\u1f9e'), ('\u1f97', '\u1f9f'), ('\u1fa0',
+ '\u1fa8'), ('\u1fa1', '\u1fa9'), ('\u1fa2', '\u1faa'), ('\u1fa3', '\u1fab'), ('\u1fa4',
+ '\u1fac'), ('\u1fa5', '\u1fad'), ('\u1fa6', '\u1fae'), ('\u1fa7', '\u1faf'), ('\u1fb0',
+ '\u1fb8'), ('\u1fb1', '\u1fb9'), ('\u1fb3', '\u1fbc'), ('\u1fbe', '\u0399'), ('\u1fc3',
+ '\u1fcc'), ('\u1fd0', '\u1fd8'), ('\u1fd1', '\u1fd9'), ('\u1fe0', '\u1fe8'), ('\u1fe1',
+ '\u1fe9'), ('\u1fe5', '\u1fec'), ('\u1ff3', '\u1ffc'), ('\u214e', '\u2132'), ('\u2184',
+ '\u2183'), ('\u2c30', '\u2c00'), ('\u2c31', '\u2c01'), ('\u2c32', '\u2c02'), ('\u2c33',
+ '\u2c03'), ('\u2c34', '\u2c04'), ('\u2c35', '\u2c05'), ('\u2c36', '\u2c06'), ('\u2c37',
+ '\u2c07'), ('\u2c38', '\u2c08'), ('\u2c39', '\u2c09'), ('\u2c3a', '\u2c0a'), ('\u2c3b',
+ '\u2c0b'), ('\u2c3c', '\u2c0c'), ('\u2c3d', '\u2c0d'), ('\u2c3e', '\u2c0e'), ('\u2c3f',
+ '\u2c0f'), ('\u2c40', '\u2c10'), ('\u2c41', '\u2c11'), ('\u2c42', '\u2c12'), ('\u2c43',
+ '\u2c13'), ('\u2c44', '\u2c14'), ('\u2c45', '\u2c15'), ('\u2c46', '\u2c16'), ('\u2c47',
+ '\u2c17'), ('\u2c48', '\u2c18'), ('\u2c49', '\u2c19'), ('\u2c4a', '\u2c1a'), ('\u2c4b',
+ '\u2c1b'), ('\u2c4c', '\u2c1c'), ('\u2c4d', '\u2c1d'), ('\u2c4e', '\u2c1e'), ('\u2c4f',
+ '\u2c1f'), ('\u2c50', '\u2c20'), ('\u2c51', '\u2c21'), ('\u2c52', '\u2c22'), ('\u2c53',
+ '\u2c23'), ('\u2c54', '\u2c24'), ('\u2c55', '\u2c25'), ('\u2c56', '\u2c26'), ('\u2c57',
+ '\u2c27'), ('\u2c58', '\u2c28'), ('\u2c59', '\u2c29'), ('\u2c5a', '\u2c2a'), ('\u2c5b',
+ '\u2c2b'), ('\u2c5c', '\u2c2c'), ('\u2c5d', '\u2c2d'), ('\u2c5e', '\u2c2e'), ('\u2c61',
+ '\u2c60'), ('\u2c65', '\u023a'), ('\u2c66', '\u023e'), ('\u2c68', '\u2c67'), ('\u2c6a',
+ '\u2c69'), ('\u2c6c', '\u2c6b'), ('\u2c73', '\u2c72'), ('\u2c76', '\u2c75'), ('\u2c81',
+ '\u2c80'), ('\u2c83', '\u2c82'), ('\u2c85', '\u2c84'), ('\u2c87', '\u2c86'), ('\u2c89',
+ '\u2c88'), ('\u2c8b', '\u2c8a'), ('\u2c8d', '\u2c8c'), ('\u2c8f', '\u2c8e'), ('\u2c91',
+ '\u2c90'), ('\u2c93', '\u2c92'), ('\u2c95', '\u2c94'), ('\u2c97', '\u2c96'), ('\u2c99',
+ '\u2c98'), ('\u2c9b', '\u2c9a'), ('\u2c9d', '\u2c9c'), ('\u2c9f', '\u2c9e'), ('\u2ca1',
+ '\u2ca0'), ('\u2ca3', '\u2ca2'), ('\u2ca5', '\u2ca4'), ('\u2ca7', '\u2ca6'), ('\u2ca9',
+ '\u2ca8'), ('\u2cab', '\u2caa'), ('\u2cad', '\u2cac'), ('\u2caf', '\u2cae'), ('\u2cb1',
+ '\u2cb0'), ('\u2cb3', '\u2cb2'), ('\u2cb5', '\u2cb4'), ('\u2cb7', '\u2cb6'), ('\u2cb9',
+ '\u2cb8'), ('\u2cbb', '\u2cba'), ('\u2cbd', '\u2cbc'), ('\u2cbf', '\u2cbe'), ('\u2cc1',
+ '\u2cc0'), ('\u2cc3', '\u2cc2'), ('\u2cc5', '\u2cc4'), ('\u2cc7', '\u2cc6'), ('\u2cc9',
+ '\u2cc8'), ('\u2ccb', '\u2cca'), ('\u2ccd', '\u2ccc'), ('\u2ccf', '\u2cce'), ('\u2cd1',
+ '\u2cd0'), ('\u2cd3', '\u2cd2'), ('\u2cd5', '\u2cd4'), ('\u2cd7', '\u2cd6'), ('\u2cd9',
+ '\u2cd8'), ('\u2cdb', '\u2cda'), ('\u2cdd', '\u2cdc'), ('\u2cdf', '\u2cde'), ('\u2ce1',
+ '\u2ce0'), ('\u2ce3', '\u2ce2'), ('\u2cec', '\u2ceb'), ('\u2cee', '\u2ced'), ('\u2cf3',
+ '\u2cf2'), ('\u2d00', '\u10a0'), ('\u2d01', '\u10a1'), ('\u2d02', '\u10a2'), ('\u2d03',
+ '\u10a3'), ('\u2d04', '\u10a4'), ('\u2d05', '\u10a5'), ('\u2d06', '\u10a6'), ('\u2d07',
+ '\u10a7'), ('\u2d08', '\u10a8'), ('\u2d09', '\u10a9'), ('\u2d0a', '\u10aa'), ('\u2d0b',
+ '\u10ab'), ('\u2d0c', '\u10ac'), ('\u2d0d', '\u10ad'), ('\u2d0e', '\u10ae'), ('\u2d0f',
+ '\u10af'), ('\u2d10', '\u10b0'), ('\u2d11', '\u10b1'), ('\u2d12', '\u10b2'), ('\u2d13',
+ '\u10b3'), ('\u2d14', '\u10b4'), ('\u2d15', '\u10b5'), ('\u2d16', '\u10b6'), ('\u2d17',
+ '\u10b7'), ('\u2d18', '\u10b8'), ('\u2d19', '\u10b9'), ('\u2d1a', '\u10ba'), ('\u2d1b',
+ '\u10bb'), ('\u2d1c', '\u10bc'), ('\u2d1d', '\u10bd'), ('\u2d1e', '\u10be'), ('\u2d1f',
+ '\u10bf'), ('\u2d20', '\u10c0'), ('\u2d21', '\u10c1'), ('\u2d22', '\u10c2'), ('\u2d23',
+ '\u10c3'), ('\u2d24', '\u10c4'), ('\u2d25', '\u10c5'), ('\u2d27', '\u10c7'), ('\u2d2d',
+ '\u10cd'), ('\ua641', '\ua640'), ('\ua643', '\ua642'), ('\ua645', '\ua644'), ('\ua647',
+ '\ua646'), ('\ua649', '\ua648'), ('\ua64b', '\ua64a'), ('\ua64d', '\ua64c'), ('\ua64f',
+ '\ua64e'), ('\ua651', '\ua650'), ('\ua653', '\ua652'), ('\ua655', '\ua654'), ('\ua657',
+ '\ua656'), ('\ua659', '\ua658'), ('\ua65b', '\ua65a'), ('\ua65d', '\ua65c'), ('\ua65f',
+ '\ua65e'), ('\ua661', '\ua660'), ('\ua663', '\ua662'), ('\ua665', '\ua664'), ('\ua667',
+ '\ua666'), ('\ua669', '\ua668'), ('\ua66b', '\ua66a'), ('\ua66d', '\ua66c'), ('\ua681',
+ '\ua680'), ('\ua683', '\ua682'), ('\ua685', '\ua684'), ('\ua687', '\ua686'), ('\ua689',
+ '\ua688'), ('\ua68b', '\ua68a'), ('\ua68d', '\ua68c'), ('\ua68f', '\ua68e'), ('\ua691',
+ '\ua690'), ('\ua693', '\ua692'), ('\ua695', '\ua694'), ('\ua697', '\ua696'), ('\ua699',
+ '\ua698'), ('\ua69b', '\ua69a'), ('\ua723', '\ua722'), ('\ua725', '\ua724'), ('\ua727',
+ '\ua726'), ('\ua729', '\ua728'), ('\ua72b', '\ua72a'), ('\ua72d', '\ua72c'), ('\ua72f',
+ '\ua72e'), ('\ua733', '\ua732'), ('\ua735', '\ua734'), ('\ua737', '\ua736'), ('\ua739',
+ '\ua738'), ('\ua73b', '\ua73a'), ('\ua73d', '\ua73c'), ('\ua73f', '\ua73e'), ('\ua741',
+ '\ua740'), ('\ua743', '\ua742'), ('\ua745', '\ua744'), ('\ua747', '\ua746'), ('\ua749',
+ '\ua748'), ('\ua74b', '\ua74a'), ('\ua74d', '\ua74c'), ('\ua74f', '\ua74e'), ('\ua751',
+ '\ua750'), ('\ua753', '\ua752'), ('\ua755', '\ua754'), ('\ua757', '\ua756'), ('\ua759',
+ '\ua758'), ('\ua75b', '\ua75a'), ('\ua75d', '\ua75c'), ('\ua75f', '\ua75e'), ('\ua761',
+ '\ua760'), ('\ua763', '\ua762'), ('\ua765', '\ua764'), ('\ua767', '\ua766'), ('\ua769',
+ '\ua768'), ('\ua76b', '\ua76a'), ('\ua76d', '\ua76c'), ('\ua76f', '\ua76e'), ('\ua77a',
+ '\ua779'), ('\ua77c', '\ua77b'), ('\ua77f', '\ua77e'), ('\ua781', '\ua780'), ('\ua783',
+ '\ua782'), ('\ua785', '\ua784'), ('\ua787', '\ua786'), ('\ua78c', '\ua78b'), ('\ua791',
+ '\ua790'), ('\ua793', '\ua792'), ('\ua797', '\ua796'), ('\ua799', '\ua798'), ('\ua79b',
+ '\ua79a'), ('\ua79d', '\ua79c'), ('\ua79f', '\ua79e'), ('\ua7a1', '\ua7a0'), ('\ua7a3',
+ '\ua7a2'), ('\ua7a5', '\ua7a4'), ('\ua7a7', '\ua7a6'), ('\ua7a9', '\ua7a8'), ('\uff41',
+ '\uff21'), ('\uff42', '\uff22'), ('\uff43', '\uff23'), ('\uff44', '\uff24'), ('\uff45',
+ '\uff25'), ('\uff46', '\uff26'), ('\uff47', '\uff27'), ('\uff48', '\uff28'), ('\uff49',
+ '\uff29'), ('\uff4a', '\uff2a'), ('\uff4b', '\uff2b'), ('\uff4c', '\uff2c'), ('\uff4d',
+ '\uff2d'), ('\uff4e', '\uff2e'), ('\uff4f', '\uff2f'), ('\uff50', '\uff30'), ('\uff51',
+ '\uff31'), ('\uff52', '\uff32'), ('\uff53', '\uff33'), ('\uff54', '\uff34'), ('\uff55',
+ '\uff35'), ('\uff56', '\uff36'), ('\uff57', '\uff37'), ('\uff58', '\uff38'), ('\uff59',
+ '\uff39'), ('\uff5a', '\uff3a'), ('\U00010428', '\U00010400'), ('\U00010429', '\U00010401'),
+ ('\U0001042a', '\U00010402'), ('\U0001042b', '\U00010403'), ('\U0001042c', '\U00010404'),
+ ('\U0001042d', '\U00010405'), ('\U0001042e', '\U00010406'), ('\U0001042f', '\U00010407'),
+ ('\U00010430', '\U00010408'), ('\U00010431', '\U00010409'), ('\U00010432', '\U0001040a'),
+ ('\U00010433', '\U0001040b'), ('\U00010434', '\U0001040c'), ('\U00010435', '\U0001040d'),
+ ('\U00010436', '\U0001040e'), ('\U00010437', '\U0001040f'), ('\U00010438', '\U00010410'),
+ ('\U00010439', '\U00010411'), ('\U0001043a', '\U00010412'), ('\U0001043b', '\U00010413'),
+ ('\U0001043c', '\U00010414'), ('\U0001043d', '\U00010415'), ('\U0001043e', '\U00010416'),
+ ('\U0001043f', '\U00010417'), ('\U00010440', '\U00010418'), ('\U00010441', '\U00010419'),
+ ('\U00010442', '\U0001041a'), ('\U00010443', '\U0001041b'), ('\U00010444', '\U0001041c'),
+ ('\U00010445', '\U0001041d'), ('\U00010446', '\U0001041e'), ('\U00010447', '\U0001041f'),
+ ('\U00010448', '\U00010420'), ('\U00010449', '\U00010421'), ('\U0001044a', '\U00010422'),
+ ('\U0001044b', '\U00010423'), ('\U0001044c', '\U00010424'), ('\U0001044d', '\U00010425'),
+ ('\U0001044e', '\U00010426'), ('\U0001044f', '\U00010427'), ('\U000118c0', '\U000118a0'),
+ ('\U000118c1', '\U000118a1'), ('\U000118c2', '\U000118a2'), ('\U000118c3', '\U000118a3'),
+ ('\U000118c4', '\U000118a4'), ('\U000118c5', '\U000118a5'), ('\U000118c6', '\U000118a6'),
+ ('\U000118c7', '\U000118a7'), ('\U000118c8', '\U000118a8'), ('\U000118c9', '\U000118a9'),
+ ('\U000118ca', '\U000118aa'), ('\U000118cb', '\U000118ab'), ('\U000118cc', '\U000118ac'),
+ ('\U000118cd', '\U000118ad'), ('\U000118ce', '\U000118ae'), ('\U000118cf', '\U000118af'),
+ ('\U000118d0', '\U000118b0'), ('\U000118d1', '\U000118b1'), ('\U000118d2', '\U000118b2'),
+ ('\U000118d3', '\U000118b3'), ('\U000118d4', '\U000118b4'), ('\U000118d5', '\U000118b5'),
+ ('\U000118d6', '\U000118b6'), ('\U000118d7', '\U000118b7'), ('\U000118d8', '\U000118b8'),
+ ('\U000118d9', '\U000118b9'), ('\U000118da', '\U000118ba'), ('\U000118db', '\U000118bb'),
+ ('\U000118dc', '\U000118bc'), ('\U000118dd', '\U000118bd'), ('\U000118de', '\U000118be'),
+ ('\U000118df', '\U000118bf')
+ ];
+
+}
+
+pub mod charwidth {
+ use core::option::{Option, Some, None};
+ use core::slice::ImmutableVector;
+
+ fn bsearch_range_value_table(c: char, is_cjk: bool, r: &'static [(char, char, u8, u8)]) -> u8 {
+ use core::cmp::{Equal, Less, Greater};
+ match r.bsearch(|&(lo, hi, _, _)| {
+ if lo <= c && c <= hi { Equal }
+ else if hi < c { Less }
+ else { Greater }
+ }) {
+ Some(idx) => {
+ let (_, _, r_ncjk, r_cjk) = r[idx];
+ if is_cjk { r_cjk } else { r_ncjk }
+ }
+ None => 1
+ }
+ }
+
+ pub fn width(c: char, is_cjk: bool) -> Option<uint> {
+ match c as uint {
+ _c @ 0 => Some(0), // null is zero width
+ cu if cu < 0x20 => None, // control sequences have no width
+ cu if cu < 0x7F => Some(1), // ASCII
+ cu if cu < 0xA0 => None, // more control sequences
+ _ => Some(bsearch_range_value_table(c, is_cjk, charwidth_table) as uint)
+ }
+ }
+
+ // character width table. Based on Markus Kuhn's free wcwidth() implementation,
+ // http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
+ static charwidth_table: &'static [(char, char, u8, u8)] = &[
+ ('\xa1', '\xa1', 1, 2), ('\xa4', '\xa4', 1, 2), ('\xa7', '\xa8', 1, 2), ('\xaa', '\xaa', 1,
+ 2), ('\xae', '\xae', 1, 2), ('\xb0', '\xb4', 1, 2), ('\xb6', '\xba', 1, 2), ('\xbc', '\xbf',
+ 1, 2), ('\xc6', '\xc6', 1, 2), ('\xd0', '\xd0', 1, 2), ('\xd7', '\xd8', 1, 2), ('\xde',
+ '\xe1', 1, 2), ('\xe6', '\xe6', 1, 2), ('\xe8', '\xea', 1, 2), ('\xec', '\xed', 1, 2),
+ ('\xf0', '\xf0', 1, 2), ('\xf2', '\xf3', 1, 2), ('\xf7', '\xfa', 1, 2), ('\xfc', '\xfc', 1,
+ 2), ('\xfe', '\xfe', 1, 2), ('\u0101', '\u0101', 1, 2), ('\u0111', '\u0111', 1, 2),
+ ('\u0113', '\u0113', 1, 2), ('\u011b', '\u011b', 1, 2), ('\u0126', '\u0127', 1, 2),
+ ('\u012b', '\u012b', 1, 2), ('\u0131', '\u0133', 1, 2), ('\u0138', '\u0138', 1, 2),
+ ('\u013f', '\u0142', 1, 2), ('\u0144', '\u0144', 1, 2), ('\u0148', '\u014b', 1, 2),
+ ('\u014d', '\u014d', 1, 2), ('\u0152', '\u0153', 1, 2), ('\u0166', '\u0167', 1, 2),
+ ('\u016b', '\u016b', 1, 2), ('\u01ce', '\u01ce', 1, 2), ('\u01d0', '\u01d0', 1, 2),
+ ('\u01d2', '\u01d2', 1, 2), ('\u01d4', '\u01d4', 1, 2), ('\u01d6', '\u01d6', 1, 2),
+ ('\u01d8', '\u01d8', 1, 2), ('\u01da', '\u01da', 1, 2), ('\u01dc', '\u01dc', 1, 2),
+ ('\u0251', '\u0251', 1, 2), ('\u0261', '\u0261', 1, 2), ('\u02c4', '\u02c4', 1, 2),
+ ('\u02c7', '\u02c7', 1, 2), ('\u02c9', '\u02cb', 1, 2), ('\u02cd', '\u02cd', 1, 2),
+ ('\u02d0', '\u02d0', 1, 2), ('\u02d8', '\u02db', 1, 2), ('\u02dd', '\u02dd', 1, 2),
+ ('\u02df', '\u02df', 1, 2), ('\u0300', '\u036f', 0, 0), ('\u0391', '\u03a1', 1, 2),
+ ('\u03a3', '\u03a9', 1, 2), ('\u03b1', '\u03c1', 1, 2), ('\u03c3', '\u03c9', 1, 2),
+ ('\u0401', '\u0401', 1, 2), ('\u0410', '\u044f', 1, 2), ('\u0451', '\u0451', 1, 2),
+ ('\u0483', '\u0489', 0, 0), ('\u0591', '\u05bd', 0, 0), ('\u05bf', '\u05bf', 0, 0),
+ ('\u05c1', '\u05c2', 0, 0), ('\u05c4', '\u05c5', 0, 0), ('\u05c7', '\u05c7', 0, 0),
+ ('\u0600', '\u0605', 0, 0), ('\u0610', '\u061a', 0, 0), ('\u061c', '\u061c', 0, 0),
+ ('\u064b', '\u065f', 0, 0), ('\u0670', '\u0670', 0, 0), ('\u06d6', '\u06dd', 0, 0),
+ ('\u06df', '\u06e4', 0, 0), ('\u06e7', '\u06e8', 0, 0), ('\u06ea', '\u06ed', 0, 0),
+ ('\u070f', '\u070f', 0, 0), ('\u0711', '\u0711', 0, 0), ('\u0730', '\u074a', 0, 0),
+ ('\u07a6', '\u07b0', 0, 0), ('\u07eb', '\u07f3', 0, 0), ('\u0816', '\u0819', 0, 0),
+ ('\u081b', '\u0823', 0, 0), ('\u0825', '\u0827', 0, 0), ('\u0829', '\u082d', 0, 0),
+ ('\u0859', '\u085b', 0, 0), ('\u08e4', '\u0902', 0, 0), ('\u093a', '\u093a', 0, 0),
+ ('\u093c', '\u093c', 0, 0), ('\u0941', '\u0948', 0, 0), ('\u094d', '\u094d', 0, 0),
+ ('\u0951', '\u0957', 0, 0), ('\u0962', '\u0963', 0, 0), ('\u0981', '\u0981', 0, 0),
+ ('\u09bc', '\u09bc', 0, 0), ('\u09c1', '\u09c4', 0, 0), ('\u09cd', '\u09cd', 0, 0),
+ ('\u09e2', '\u09e3', 0, 0), ('\u0a01', '\u0a02', 0, 0), ('\u0a3c', '\u0a3c', 0, 0),
+ ('\u0a41', '\u0a42', 0, 0), ('\u0a47', '\u0a48', 0, 0), ('\u0a4b', '\u0a4d', 0, 0),
+ ('\u0a51', '\u0a51', 0, 0), ('\u0a70', '\u0a71', 0, 0), ('\u0a75', '\u0a75', 0, 0),
+ ('\u0a81', '\u0a82', 0, 0), ('\u0abc', '\u0abc', 0, 0), ('\u0ac1', '\u0ac5', 0, 0),
+ ('\u0ac7', '\u0ac8', 0, 0), ('\u0acd', '\u0acd', 0, 0), ('\u0ae2', '\u0ae3', 0, 0),
+ ('\u0b01', '\u0b01', 0, 0), ('\u0b3c', '\u0b3c', 0, 0), ('\u0b3f', '\u0b3f', 0, 0),
+ ('\u0b41', '\u0b44', 0, 0), ('\u0b4d', '\u0b4d', 0, 0), ('\u0b56', '\u0b56', 0, 0),
+ ('\u0b62', '\u0b63', 0, 0), ('\u0b82', '\u0b82', 0, 0), ('\u0bc0', '\u0bc0', 0, 0),
+ ('\u0bcd', '\u0bcd', 0, 0), ('\u0c00', '\u0c00', 0, 0), ('\u0c3e', '\u0c40', 0, 0),
+ ('\u0c46', '\u0c48', 0, 0), ('\u0c4a', '\u0c4d', 0, 0), ('\u0c55', '\u0c56', 0, 0),
+ ('\u0c62', '\u0c63', 0, 0), ('\u0c81', '\u0c81', 0, 0), ('\u0cbc', '\u0cbc', 0, 0),
+ ('\u0cbf', '\u0cbf', 0, 0), ('\u0cc6', '\u0cc6', 0, 0), ('\u0ccc', '\u0ccd', 0, 0),
+ ('\u0ce2', '\u0ce3', 0, 0), ('\u0d01', '\u0d01', 0, 0), ('\u0d41', '\u0d44', 0, 0),
+ ('\u0d4d', '\u0d4d', 0, 0), ('\u0d62', '\u0d63', 0, 0), ('\u0dca', '\u0dca', 0, 0),
+ ('\u0dd2', '\u0dd4', 0, 0), ('\u0dd6', '\u0dd6', 0, 0), ('\u0e31', '\u0e31', 0, 0),
+ ('\u0e34', '\u0e3a', 0, 0), ('\u0e47', '\u0e4e', 0, 0), ('\u0eb1', '\u0eb1', 0, 0),
+ ('\u0eb4', '\u0eb9', 0, 0), ('\u0ebb', '\u0ebc', 0, 0), ('\u0ec8', '\u0ecd', 0, 0),
+ ('\u0f18', '\u0f19', 0, 0), ('\u0f35', '\u0f35', 0, 0), ('\u0f37', '\u0f37', 0, 0),
+ ('\u0f39', '\u0f39', 0, 0), ('\u0f71', '\u0f7e', 0, 0), ('\u0f80', '\u0f84', 0, 0),
+ ('\u0f86', '\u0f87', 0, 0), ('\u0f8d', '\u0f97', 0, 0), ('\u0f99', '\u0fbc', 0, 0),
+ ('\u0fc6', '\u0fc6', 0, 0), ('\u102d', '\u1030', 0, 0), ('\u1032', '\u1037', 0, 0),
+ ('\u1039', '\u103a', 0, 0), ('\u103d', '\u103e', 0, 0), ('\u1058', '\u1059', 0, 0),
+ ('\u105e', '\u1060', 0, 0), ('\u1071', '\u1074', 0, 0), ('\u1082', '\u1082', 0, 0),
+ ('\u1085', '\u1086', 0, 0), ('\u108d', '\u108d', 0, 0), ('\u109d', '\u109d', 0, 0),
+ ('\u1100', '\u115f', 2, 2), ('\u1160', '\u11ff', 0, 0), ('\u135d', '\u135f', 0, 0),
+ ('\u1712', '\u1714', 0, 0), ('\u1732', '\u1734', 0, 0), ('\u1752', '\u1753', 0, 0),
+ ('\u1772', '\u1773', 0, 0), ('\u17b4', '\u17b5', 0, 0), ('\u17b7', '\u17bd', 0, 0),
+ ('\u17c6', '\u17c6', 0, 0), ('\u17c9', '\u17d3', 0, 0), ('\u17dd', '\u17dd', 0, 0),
+ ('\u180b', '\u180e', 0, 0), ('\u18a9', '\u18a9', 0, 0), ('\u1920', '\u1922', 0, 0),
+ ('\u1927', '\u1928', 0, 0), ('\u1932', '\u1932', 0, 0), ('\u1939', '\u193b', 0, 0),
+ ('\u1a17', '\u1a18', 0, 0), ('\u1a1b', '\u1a1b', 0, 0), ('\u1a56', '\u1a56', 0, 0),
+ ('\u1a58', '\u1a5e', 0, 0), ('\u1a60', '\u1a60', 0, 0), ('\u1a62', '\u1a62', 0, 0),
+ ('\u1a65', '\u1a6c', 0, 0), ('\u1a73', '\u1a7c', 0, 0), ('\u1a7f', '\u1a7f', 0, 0),
+ ('\u1ab0', '\u1abe', 0, 0), ('\u1b00', '\u1b03', 0, 0), ('\u1b34', '\u1b34', 0, 0),
+ ('\u1b36', '\u1b3a', 0, 0), ('\u1b3c', '\u1b3c', 0, 0), ('\u1b42', '\u1b42', 0, 0),
+ ('\u1b6b', '\u1b73', 0, 0), ('\u1b80', '\u1b81', 0, 0), ('\u1ba2', '\u1ba5', 0, 0),
+ ('\u1ba8', '\u1ba9', 0, 0), ('\u1bab', '\u1bad', 0, 0), ('\u1be6', '\u1be6', 0, 0),
+ ('\u1be8', '\u1be9', 0, 0), ('\u1bed', '\u1bed', 0, 0), ('\u1bef', '\u1bf1', 0, 0),
+ ('\u1c2c', '\u1c33', 0, 0), ('\u1c36', '\u1c37', 0, 0), ('\u1cd0', '\u1cd2', 0, 0),
+ ('\u1cd4', '\u1ce0', 0, 0), ('\u1ce2', '\u1ce8', 0, 0), ('\u1ced', '\u1ced', 0, 0),
+ ('\u1cf4', '\u1cf4', 0, 0), ('\u1cf8', '\u1cf9', 0, 0), ('\u1dc0', '\u1df5', 0, 0),
+ ('\u1dfc', '\u1dff', 0, 0), ('\u200b', '\u200f', 0, 0), ('\u2010', '\u2010', 1, 2),
+ ('\u2013', '\u2016', 1, 2), ('\u2018', '\u2019', 1, 2), ('\u201c', '\u201d', 1, 2),
+ ('\u2020', '\u2022', 1, 2), ('\u2024', '\u2027', 1, 2), ('\u202a', '\u202e', 0, 0),
+ ('\u2030', '\u2030', 1, 2), ('\u2032', '\u2033', 1, 2), ('\u2035', '\u2035', 1, 2),
+ ('\u203b', '\u203b', 1, 2), ('\u203e', '\u203e', 1, 2), ('\u2060', '\u2064', 0, 0),
+ ('\u2066', '\u206f', 0, 0), ('\u2074', '\u2074', 1, 2), ('\u207f', '\u207f', 1, 2),
+ ('\u2081', '\u2084', 1, 2), ('\u20ac', '\u20ac', 1, 2), ('\u20d0', '\u20f0', 0, 0),
+ ('\u2103', '\u2103', 1, 2), ('\u2105', '\u2105', 1, 2), ('\u2109', '\u2109', 1, 2),
+ ('\u2113', '\u2113', 1, 2), ('\u2116', '\u2116', 1, 2), ('\u2121', '\u2122', 1, 2),
+ ('\u2126', '\u2126', 1, 2), ('\u212b', '\u212b', 1, 2), ('\u2153', '\u2154', 1, 2),
+ ('\u215b', '\u215e', 1, 2), ('\u2160', '\u216b', 1, 2), ('\u2170', '\u2179', 1, 2),
+ ('\u2189', '\u2189', 1, 2), ('\u2190', '\u2199', 1, 2), ('\u21b8', '\u21b9', 1, 2),
+ ('\u21d2', '\u21d2', 1, 2), ('\u21d4', '\u21d4', 1, 2), ('\u21e7', '\u21e7', 1, 2),
+ ('\u2200', '\u2200', 1, 2), ('\u2202', '\u2203', 1, 2), ('\u2207', '\u2208', 1, 2),
+ ('\u220b', '\u220b', 1, 2), ('\u220f', '\u220f', 1, 2), ('\u2211', '\u2211', 1, 2),
+ ('\u2215', '\u2215', 1, 2), ('\u221a', '\u221a', 1, 2), ('\u221d', '\u2220', 1, 2),
+ ('\u2223', '\u2223', 1, 2), ('\u2225', '\u2225', 1, 2), ('\u2227', '\u222c', 1, 2),
+ ('\u222e', '\u222e', 1, 2), ('\u2234', '\u2237', 1, 2), ('\u223c', '\u223d', 1, 2),
+ ('\u2248', '\u2248', 1, 2), ('\u224c', '\u224c', 1, 2), ('\u2252', '\u2252', 1, 2),
+ ('\u2260', '\u2261', 1, 2), ('\u2264', '\u2267', 1, 2), ('\u226a', '\u226b', 1, 2),
+ ('\u226e', '\u226f', 1, 2), ('\u2282', '\u2283', 1, 2), ('\u2286', '\u2287', 1, 2),
+ ('\u2295', '\u2295', 1, 2), ('\u2299', '\u2299', 1, 2), ('\u22a5', '\u22a5', 1, 2),
+ ('\u22bf', '\u22bf', 1, 2), ('\u2312', '\u2312', 1, 2), ('\u2329', '\u232a', 2, 2),
+ ('\u2460', '\u24e9', 1, 2), ('\u24eb', '\u254b', 1, 2), ('\u2550', '\u2573', 1, 2),
+ ('\u2580', '\u258f', 1, 2), ('\u2592', '\u2595', 1, 2), ('\u25a0', '\u25a1', 1, 2),
+ ('\u25a3', '\u25a9', 1, 2), ('\u25b2', '\u25b3', 1, 2), ('\u25b6', '\u25b7', 1, 2),
+ ('\u25bc', '\u25bd', 1, 2), ('\u25c0', '\u25c1', 1, 2), ('\u25c6', '\u25c8', 1, 2),
+ ('\u25cb', '\u25cb', 1, 2), ('\u25ce', '\u25d1', 1, 2), ('\u25e2', '\u25e5', 1, 2),
+ ('\u25ef', '\u25ef', 1, 2), ('\u2605', '\u2606', 1, 2), ('\u2609', '\u2609', 1, 2),
+ ('\u260e', '\u260f', 1, 2), ('\u2614', '\u2615', 1, 2), ('\u261c', '\u261c', 1, 2),
+ ('\u261e', '\u261e', 1, 2), ('\u2640', '\u2640', 1, 2), ('\u2642', '\u2642', 1, 2),
+ ('\u2660', '\u2661', 1, 2), ('\u2663', '\u2665', 1, 2), ('\u2667', '\u266a', 1, 2),
+ ('\u266c', '\u266d', 1, 2), ('\u266f', '\u266f', 1, 2), ('\u269e', '\u269f', 1, 2),
+ ('\u26be', '\u26bf', 1, 2), ('\u26c4', '\u26cd', 1, 2), ('\u26cf', '\u26e1', 1, 2),
+ ('\u26e3', '\u26e3', 1, 2), ('\u26e8', '\u26ff', 1, 2), ('\u273d', '\u273d', 1, 2),
+ ('\u2757', '\u2757', 1, 2), ('\u2776', '\u277f', 1, 2), ('\u2b55', '\u2b59', 1, 2),
+ ('\u2cef', '\u2cf1', 0, 0), ('\u2d7f', '\u2d7f', 0, 0), ('\u2de0', '\u2dff', 0, 0),
+ ('\u2e80', '\u2e99', 2, 2), ('\u2e9b', '\u2ef3', 2, 2), ('\u2f00', '\u2fd5', 2, 2),
+ ('\u2ff0', '\u2ffb', 2, 2), ('\u3000', '\u3029', 2, 2), ('\u302a', '\u302d', 0, 0),
+ ('\u302e', '\u303e', 2, 2), ('\u3041', '\u3096', 2, 2), ('\u3099', '\u309a', 0, 0),
+ ('\u309b', '\u30ff', 2, 2), ('\u3105', '\u312d', 2, 2), ('\u3131', '\u318e', 2, 2),
+ ('\u3190', '\u31ba', 2, 2), ('\u31c0', '\u31e3', 2, 2), ('\u31f0', '\u321e', 2, 2),
+ ('\u3220', '\u3247', 2, 2), ('\u3248', '\u324f', 1, 2), ('\u3250', '\u32fe', 2, 2),
+ ('\u3300', '\u4dbf', 2, 2), ('\u4e00', '\ua48c', 2, 2), ('\ua490', '\ua4c6', 2, 2),
+ ('\ua66f', '\ua672', 0, 0), ('\ua674', '\ua67d', 0, 0), ('\ua69f', '\ua69f', 0, 0),
+ ('\ua6f0', '\ua6f1', 0, 0), ('\ua802', '\ua802', 0, 0), ('\ua806', '\ua806', 0, 0),
+ ('\ua80b', '\ua80b', 0, 0), ('\ua825', '\ua826', 0, 0), ('\ua8c4', '\ua8c4', 0, 0),
+ ('\ua8e0', '\ua8f1', 0, 0), ('\ua926', '\ua92d', 0, 0), ('\ua947', '\ua951', 0, 0),
+ ('\ua960', '\ua97c', 2, 2), ('\ua980', '\ua982', 0, 0), ('\ua9b3', '\ua9b3', 0, 0),
+ ('\ua9b6', '\ua9b9', 0, 0), ('\ua9bc', '\ua9bc', 0, 0), ('\ua9e5', '\ua9e5', 0, 0),
+ ('\uaa29', '\uaa2e', 0, 0), ('\uaa31', '\uaa32', 0, 0), ('\uaa35', '\uaa36', 0, 0),
+ ('\uaa43', '\uaa43', 0, 0), ('\uaa4c', '\uaa4c', 0, 0), ('\uaa7c', '\uaa7c', 0, 0),
+ ('\uaab0', '\uaab0', 0, 0), ('\uaab2', '\uaab4', 0, 0), ('\uaab7', '\uaab8', 0, 0),
+ ('\uaabe', '\uaabf', 0, 0), ('\uaac1', '\uaac1', 0, 0), ('\uaaec', '\uaaed', 0, 0),
+ ('\uaaf6', '\uaaf6', 0, 0), ('\uabe5', '\uabe5', 0, 0), ('\uabe8', '\uabe8', 0, 0),
+ ('\uabed', '\uabed', 0, 0), ('\uac00', '\ud7a3', 2, 2), ('\ue000', '\uf8ff', 1, 2),
+ ('\uf900', '\ufaff', 2, 2), ('\ufb1e', '\ufb1e', 0, 0), ('\ufe00', '\ufe0f', 0, 0),
+ ('\ufe10', '\ufe19', 2, 2), ('\ufe20', '\ufe2d', 0, 0), ('\ufe30', '\ufe52', 2, 2),
+ ('\ufe54', '\ufe66', 2, 2), ('\ufe68', '\ufe6b', 2, 2), ('\ufeff', '\ufeff', 0, 0),
+ ('\uff01', '\uff60', 2, 2), ('\uffe0', '\uffe6', 2, 2), ('\ufff9', '\ufffb', 0, 0),
+ ('\ufffd', '\ufffd', 1, 2), ('\U000101fd', '\U000101fd', 0, 0), ('\U000102e0', '\U000102e0',
+ 0, 0), ('\U00010376', '\U0001037a', 0, 0), ('\U00010a01', '\U00010a03', 0, 0),
+ ('\U00010a05', '\U00010a06', 0, 0), ('\U00010a0c', '\U00010a0f', 0, 0), ('\U00010a38',
+ '\U00010a3a', 0, 0), ('\U00010a3f', '\U00010a3f', 0, 0), ('\U00010ae5', '\U00010ae6', 0, 0),
+ ('\U00011001', '\U00011001', 0, 0), ('\U00011038', '\U00011046', 0, 0), ('\U0001107f',
+ '\U00011081', 0, 0), ('\U000110b3', '\U000110b6', 0, 0), ('\U000110b9', '\U000110ba', 0, 0),
+ ('\U000110bd', '\U000110bd', 0, 0), ('\U00011100', '\U00011102', 0, 0), ('\U00011127',
+ '\U0001112b', 0, 0), ('\U0001112d', '\U00011134', 0, 0), ('\U00011173', '\U00011173', 0, 0),
+ ('\U00011180', '\U00011181', 0, 0), ('\U000111b6', '\U000111be', 0, 0), ('\U0001122f',
+ '\U00011231', 0, 0), ('\U00011234', '\U00011234', 0, 0), ('\U00011236', '\U00011237', 0, 0),
+ ('\U000112df', '\U000112df', 0, 0), ('\U000112e3', '\U000112ea', 0, 0), ('\U00011301',
+ '\U00011301', 0, 0), ('\U0001133c', '\U0001133c', 0, 0), ('\U00011340', '\U00011340', 0, 0),
+ ('\U00011366', '\U0001136c', 0, 0), ('\U00011370', '\U00011374', 0, 0), ('\U000114b3',
+ '\U000114b8', 0, 0), ('\U000114ba', '\U000114ba', 0, 0), ('\U000114bf', '\U000114c0', 0, 0),
+ ('\U000114c2', '\U000114c3', 0, 0), ('\U000115b2', '\U000115b5', 0, 0), ('\U000115bc',
+ '\U000115bd', 0, 0), ('\U000115bf', '\U000115c0', 0, 0), ('\U00011633', '\U0001163a', 0, 0),
+ ('\U0001163d', '\U0001163d', 0, 0), ('\U0001163f', '\U00011640', 0, 0), ('\U000116ab',
+ '\U000116ab', 0, 0), ('\U000116ad', '\U000116ad', 0, 0), ('\U000116b0', '\U000116b5', 0, 0),
+ ('\U000116b7', '\U000116b7', 0, 0), ('\U00016af0', '\U00016af4', 0, 0), ('\U00016b30',
+ '\U00016b36', 0, 0), ('\U00016f8f', '\U00016f92', 0, 0), ('\U0001b000', '\U0001b001', 2, 2),
+ ('\U0001bc9d', '\U0001bc9e', 0, 0), ('\U0001bca0', '\U0001bca3', 0, 0), ('\U0001d167',
+ '\U0001d169', 0, 0), ('\U0001d173', '\U0001d182', 0, 0), ('\U0001d185', '\U0001d18b', 0, 0),
+ ('\U0001d1aa', '\U0001d1ad', 0, 0), ('\U0001d242', '\U0001d244', 0, 0), ('\U0001e8d0',
+ '\U0001e8d6', 0, 0), ('\U0001f100', '\U0001f10a', 1, 2), ('\U0001f110', '\U0001f12d', 1, 2),
+ ('\U0001f130', '\U0001f169', 1, 2), ('\U0001f170', '\U0001f19a', 1, 2), ('\U0001f200',
+ '\U0001f202', 2, 2), ('\U0001f210', '\U0001f23a', 2, 2), ('\U0001f240', '\U0001f248', 2, 2),
+ ('\U0001f250', '\U0001f251', 2, 2), ('\U00020000', '\U0002fffd', 2, 2), ('\U00030000',
+ '\U0003fffd', 2, 2), ('\U000e0001', '\U000e0001', 0, 0), ('\U000e0020', '\U000e007f', 0, 0),
+ ('\U000e0100', '\U000e01ef', 0, 0), ('\U000f0000', '\U000ffffd', 1, 2), ('\U00100000',
+ '\U0010fffd', 1, 2)
+ ];
+
+}
--- /dev/null
+// Copyright 2012-2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+ * Unicode-intensive `char` methods.
+ *
+ * These methods implement functionality for `char` that requires knowledge of
+ * Unicode definitions, including normalization, categorization, and display information.
+ */
+
+use core::option::Option;
+use tables::{derived_property, property, general_category, conversions, charwidth};
+
+/// Returns whether the specified `char` is considered a Unicode alphabetic
+/// code point
+pub fn is_alphabetic(c: char) -> bool { derived_property::Alphabetic(c) }
+
+/// Returns whether the specified `char` satisfies the 'XID_Start' Unicode property
+///
+/// 'XID_Start' is a Unicode Derived Property specified in
+/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
+/// mostly similar to ID_Start but modified for closure under NFKx.
+#[allow(non_snake_case_functions)]
+pub fn is_XID_start(c: char) -> bool { derived_property::XID_Start(c) }
+
+/// Returns whether the specified `char` satisfies the 'XID_Continue' Unicode property
+///
+/// 'XID_Continue' is a Unicode Derived Property specified in
+/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
+/// mostly similar to 'ID_Continue' but modified for closure under NFKx.
+#[allow(non_snake_case_functions)]
+pub fn is_XID_continue(c: char) -> bool { derived_property::XID_Continue(c) }
+
+///
+/// Indicates whether a `char` is in lower case
+///
+/// This is defined according to the terms of the Unicode Derived Core Property 'Lowercase'.
+///
+#[inline]
+pub fn is_lowercase(c: char) -> bool { derived_property::Lowercase(c) }
+
+///
+/// Indicates whether a `char` is in upper case
+///
+/// This is defined according to the terms of the Unicode Derived Core Property 'Uppercase'.
+///
+#[inline]
+pub fn is_uppercase(c: char) -> bool { derived_property::Uppercase(c) }
+
+///
+/// Indicates whether a `char` is whitespace
+///
+/// Whitespace is defined in terms of the Unicode Property 'White_Space'.
+///
+#[inline]
+pub fn is_whitespace(c: char) -> bool {
+ // As an optimization ASCII whitespace characters are checked separately
+ c == ' '
+ || ('\x09' <= c && c <= '\x0d')
+ || property::White_Space(c)
+}
+
+///
+/// Indicates whether a `char` is alphanumeric
+///
+/// Alphanumericness is defined in terms of the Unicode General Categories
+/// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
+///
+#[inline]
+pub fn is_alphanumeric(c: char) -> bool {
+ derived_property::Alphabetic(c)
+ || general_category::N(c)
+}
+
+///
+/// Indicates whether a `char` is a control code point
+///
+/// Control code points are defined in terms of the Unicode General Category
+/// 'Cc'.
+///
+#[inline]
+pub fn is_control(c: char) -> bool { general_category::Cc(c) }
+
+/// Indicates whether the `char` is numeric (Nd, Nl, or No)
+#[inline]
+pub fn is_digit(c: char) -> bool {
+ general_category::N(c)
+}
+
+/// Convert a char to its uppercase equivalent
+///
+/// The case-folding performed is the common or simple mapping:
+/// it maps one unicode codepoint (one char in Rust) to its uppercase equivalent according
+/// to the Unicode database at ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
+/// The additional SpecialCasing.txt is not considered here, as it expands to multiple
+/// codepoints in some cases.
+///
+/// A full reference can be found here
+/// http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G33992
+///
+/// # Return value
+///
+/// Returns the char itself if no conversion was made
+#[inline]
+pub fn to_uppercase(c: char) -> char {
+ conversions::to_upper(c)
+}
+
+/// Convert a char to its lowercase equivalent
+///
+/// The case-folding performed is the common or simple mapping
+/// see `to_uppercase` for references and more information
+///
+/// # Return value
+///
+/// Returns the char itself if no conversion if possible
+#[inline]
+pub fn to_lowercase(c: char) -> char {
+ conversions::to_lower(c)
+}
+
+/// Returns this character's displayed width in columns, or `None` if it is a
+/// control character other than `'\x00'`.
+///
+/// `is_cjk` determines behavior for characters in the Ambiguous category:
+/// if `is_cjk` is `true`, these are 2 columns wide; otherwise, they are 1.
+/// In CJK contexts, `is_cjk` should be `true`, else it should be `false`.
+/// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
+/// recommends that these characters be treated as 1 column (i.e.,
+/// `is_cjk` = `false`) if the context cannot be reliably determined.
+pub fn width(c: char, is_cjk: bool) -> Option<uint> {
+ charwidth::width(c, is_cjk)
+}
+
+/// Useful functions for Unicode characters.
+pub trait UnicodeChar {
+ /// Returns whether the specified character is considered a Unicode
+ /// alphabetic code point.
+ fn is_alphabetic(&self) -> bool;
+
+ /// Returns whether the specified character satisfies the 'XID_Start'
+ /// Unicode property.
+ ///
+ /// 'XID_Start' is a Unicode Derived Property specified in
+ /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
+ /// mostly similar to ID_Start but modified for closure under NFKx.
+ #[allow(non_snake_case_functions)]
+ fn is_XID_start(&self) -> bool;
+
+ /// Returns whether the specified `char` satisfies the 'XID_Continue'
+ /// Unicode property.
+ ///
+ /// 'XID_Continue' is a Unicode Derived Property specified in
+ /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
+ /// mostly similar to 'ID_Continue' but modified for closure under NFKx.
+ #[allow(non_snake_case_functions)]
+ fn is_XID_continue(&self) -> bool;
+
+
+ /// Indicates whether a character is in lowercase.
+ ///
+ /// This is defined according to the terms of the Unicode Derived Core
+ /// Property `Lowercase`.
+ fn is_lowercase(&self) -> bool;
+
+ /// Indicates whether a character is in uppercase.
+ ///
+ /// This is defined according to the terms of the Unicode Derived Core
+ /// Property `Uppercase`.
+ fn is_uppercase(&self) -> bool;
+
+ /// Indicates whether a character is whitespace.
+ ///
+ /// Whitespace is defined in terms of the Unicode Property `White_Space`.
+ fn is_whitespace(&self) -> bool;
+
+ /// Indicates whether a character is alphanumeric.
+ ///
+ /// Alphanumericness is defined in terms of the Unicode General Categories
+ /// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
+ fn is_alphanumeric(&self) -> bool;
+
+ /// Indicates whether a character is a control code point.
+ ///
+ /// Control code points are defined in terms of the Unicode General
+ /// Category `Cc`.
+ fn is_control(&self) -> bool;
+
+ /// Indicates whether the character is numeric (Nd, Nl, or No).
+ fn is_digit(&self) -> bool;
+
+ /// Converts a character to its lowercase equivalent.
+ ///
+ /// The case-folding performed is the common or simple mapping. See
+ /// `to_uppercase()` for references and more information.
+ ///
+ /// # Return value
+ ///
+ /// Returns the lowercase equivalent of the character, or the character
+ /// itself if no conversion is possible.
+ fn to_lowercase(&self) -> char;
+
+ /// Converts a character to its uppercase equivalent.
+ ///
+ /// The case-folding performed is the common or simple mapping: it maps
+ /// one unicode codepoint (one character in Rust) to its uppercase
+ /// equivalent according to the Unicode database [1]. The additional
+ /// `SpecialCasing.txt` is not considered here, as it expands to multiple
+ /// codepoints in some cases.
+ ///
+ /// A full reference can be found here [2].
+ ///
+ /// # Return value
+ ///
+ /// Returns the uppercase equivalent of the character, or the character
+ /// itself if no conversion was made.
+ ///
+ /// [1]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
+ ///
+ /// [2]: http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G33992
+ fn to_uppercase(&self) -> char;
+
+ /// Returns this character's displayed width in columns, or `None` if it is a
+ /// control character other than `'\x00'`.
+ ///
+ /// `is_cjk` determines behavior for characters in the Ambiguous category:
+ /// if `is_cjk` is `true`, these are 2 columns wide; otherwise, they are 1.
+ /// In CJK contexts, `is_cjk` should be `true`, else it should be `false`.
+ /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
+ /// recommends that these characters be treated as 1 column (i.e.,
+ /// `is_cjk` = `false`) if the context cannot be reliably determined.
+ fn width(&self, is_cjk: bool) -> Option<uint>;
+}
+
+impl UnicodeChar for char {
+ fn is_alphabetic(&self) -> bool { is_alphabetic(*self) }
+
+ fn is_XID_start(&self) -> bool { is_XID_start(*self) }
+
+ fn is_XID_continue(&self) -> bool { is_XID_continue(*self) }
+
+ fn is_lowercase(&self) -> bool { is_lowercase(*self) }
+
+ fn is_uppercase(&self) -> bool { is_uppercase(*self) }
+
+ fn is_whitespace(&self) -> bool { is_whitespace(*self) }
+
+ fn is_alphanumeric(&self) -> bool { is_alphanumeric(*self) }
+
+ fn is_control(&self) -> bool { is_control(*self) }
+
+ fn is_digit(&self) -> bool { is_digit(*self) }
+
+ fn to_lowercase(&self) -> char { to_lowercase(*self) }
+
+ fn to_uppercase(&self) -> char { to_uppercase(*self) }
+
+ fn width(&self, is_cjk: bool) -> Option<uint> { width(*self, is_cjk) }
+}
--- /dev/null
+// Copyright 2012-2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+ * Unicode-intensive string manipulations.
+ *
+ * This module provides functionality to `str` that requires the Unicode
+ * methods provided by the UnicodeChar trait.
+ */
+
+use core::collections::Collection;
+use core::iter::{Filter};
+use core::str::{CharSplits, StrSlice};
+use core::iter::Iterator;
+use u_char;
+
+/// An iterator over the words of a string, separated by a sequence of whitespace
+pub type Words<'a> =
+ Filter<'a, &'a str, CharSplits<'a, extern "Rust" fn(char) -> bool>>;
+
+/// Methods for Unicode string slices
+pub trait UnicodeStrSlice<'a> {
+ /// An iterator over the words of a string (subsequences separated
+ /// by any sequence of whitespace). Sequences of whitespace are
+ /// collapsed, so empty "words" are not included.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// let some_words = " Mary had\ta little \n\t lamb";
+ /// let v: Vec<&str> = some_words.words().collect();
+ /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
+ /// ```
+ fn words(&self) -> Words<'a>;
+
+ /// Returns true if the string contains only whitespace.
+ ///
+ /// Whitespace characters are determined by `char::is_whitespace`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// assert!(" \t\n".is_whitespace());
+ /// assert!("".is_whitespace());
+ ///
+ /// assert!( !"abc".is_whitespace());
+ /// ```
+ fn is_whitespace(&self) -> bool;
+
+ /// Returns true if the string contains only alphanumeric code
+ /// points.
+ ///
+ /// Alphanumeric characters are determined by `char::is_alphanumeric`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// assert!("Löwe老虎Léopard123".is_alphanumeric());
+ /// assert!("".is_alphanumeric());
+ ///
+ /// assert!( !" &*~".is_alphanumeric());
+ /// ```
+ fn is_alphanumeric(&self) -> bool;
+
+ /// Returns a string's displayed width in columns, treating control
+ /// characters as zero-width.
+ ///
+ /// `is_cjk` determines behavior for characters in the Ambiguous category:
+ /// if `is_cjk` is `true`, these are 2 columns wide; otherwise, they are 1.
+ /// In CJK locales, `is_cjk` should be `true`, else it should be `false`.
+ /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
+ /// recommends that these characters be treated as 1 column (i.e.,
+ /// `is_cjk` = `false`) if the locale is unknown.
+ //fn width(&self, is_cjk: bool) -> uint;
+
+ /// Returns a string with leading and trailing whitespace removed.
+ fn trim(&self) -> &'a str;
+
+ /// Returns a string with leading whitespace removed.
+ fn trim_left(&self) -> &'a str;
+
+ /// Returns a string with trailing whitespace removed.
+ fn trim_right(&self) -> &'a str;
+}
+
+impl<'a> UnicodeStrSlice<'a> for &'a str {
+ #[inline]
+ fn words(&self) -> Words<'a> {
+ self.split(u_char::is_whitespace).filter(|s| !s.is_empty())
+ }
+
+ #[inline]
+ fn is_whitespace(&self) -> bool { self.chars().all(u_char::is_whitespace) }
+
+ #[inline]
+ fn is_alphanumeric(&self) -> bool { self.chars().all(u_char::is_alphanumeric) }
+
+ #[inline]
+ fn trim(&self) -> &'a str {
+ self.trim_left().trim_right()
+ }
+
+ #[inline]
+ fn trim_left(&self) -> &'a str {
+ self.trim_left_chars(u_char::is_whitespace)
+ }
+
+ #[inline]
+ fn trim_right(&self) -> &'a str {
+ self.trim_right_chars(u_char::is_whitespace)
+ }
+}
//! Types/fns concerning URLs (see RFC 3986)
-#![crate_id = "url#0.11.0"]
+#![crate_name = "url"]
#![experimental]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
#![feature(default_type_params)]
use std::fmt;
use std::from_str::FromStr;
use std::hash;
-use std::io::BufReader;
-use std::string::String;
use std::uint;
+use std::path::BytesContainer;
/// A Uniform Resource Locator (URL). A URL is a form of URI (Uniform Resource
/// Identifier) that includes network location information, such as hostname or
/// # Example
///
/// ```rust
-/// use url::{Url, UserInfo};
+/// use url::Url;
///
-/// let url = Url { scheme: "https".to_string(),
-/// user: Some(UserInfo { user: "username".to_string(), pass: None }),
-/// host: "example.com".to_string(),
-/// port: Some("8080".to_string()),
-/// path: "/foo/bar".to_string(),
-/// query: vec!(("baz".to_string(), "qux".to_string())),
-/// fragment: Some("quz".to_string()) };
-/// // https://username@example.com:8080/foo/bar?baz=qux#quz
+/// let raw = "https://username@example.com:8080/foo/bar?baz=qux#quz";
+/// match Url::parse(raw) {
+/// Ok(u) => println!("Parsed '{}'", u),
+/// Err(e) => println!("Couldn't parse '{}': {}", raw, e),
+/// }
/// ```
#[deriving(Clone, PartialEq, Eq)]
pub struct Url {
/// A domain name or IP address. For example, `example.com`.
pub host: String,
/// A TCP port number, for example `8080`.
- pub port: Option<String>,
- /// The path component of a URL, for example `/foo/bar`.
- pub path: String,
- /// The query component of a URL.
- /// `vec!(("baz".to_string(), "qux".to_string()))` represents the fragment
- /// `baz=qux` in the above example.
- pub query: Query,
- /// The fragment component, such as `quz`. Doesn't include the leading `#` character.
- pub fragment: Option<String>
+ pub port: Option<u16>,
+ /// The path component of a URL, for example `/foo/bar?baz=qux#quz`.
+ pub path: Path,
}
-#[deriving(Clone, PartialEq)]
+#[deriving(Clone, PartialEq, Eq)]
pub struct Path {
/// The path component of a URL, for example `/foo/bar`.
pub path: String,
/// The query component of a URL.
- /// `vec!(("baz".to_string(), "qux".to_string()))` represents the fragment
+ /// `vec![("baz".to_string(), "qux".to_string())]` represents the fragment
/// `baz=qux` in the above example.
pub query: Query,
- /// The fragment component, such as `quz`. Doesn't include the leading `#` character.
+ /// The fragment component, such as `quz`. Not including the leading `#` character.
pub fragment: Option<String>
}
pub fn new(scheme: String,
user: Option<UserInfo>,
host: String,
- port: Option<String>,
+ port: Option<u16>,
path: String,
query: Query,
fragment: Option<String>)
user: user,
host: host,
port: port,
- path: path,
- query: query,
- fragment: fragment,
+ path: Path::new(path, query, fragment)
}
}
+
+ /// Parses a URL, converting it from a string to a `Url` representation.
+ ///
+ /// # Arguments
+ /// * rawurl - a string representing the full URL, including scheme.
+ ///
+ /// # Return value
+ ///
+ /// `Err(e)` if the string did not represent a valid URL, where `e` is a
+ /// `String` error message. Otherwise, `Ok(u)` where `u` is a `Url` struct
+ /// representing the URL.
+ pub fn parse(rawurl: &str) -> DecodeResult<Url> {
+ // scheme
+ let (scheme, rest) = try!(get_scheme(rawurl));
+
+ // authority
+ let (userinfo, host, port, rest) = try!(get_authority(rest));
+
+ // path
+ let has_authority = host.len() > 0;
+ let (path, rest) = try!(get_path(rest, has_authority));
+
+ // query and fragment
+ let (query, fragment) = try!(get_query_fragment(rest));
+
+ let url = Url::new(scheme.to_string(),
+ userinfo,
+ host.to_string(),
+ port,
+ path,
+ query,
+ fragment);
+ Ok(url)
+ }
+}
+
+#[deprecated="use `Url::parse`"]
+pub fn from_str(s: &str) -> Result<Url, String> {
+ Url::parse(s)
}
impl Path {
fragment: fragment,
}
}
+
+ /// Parses a URL path, converting it from a string to a `Path` representation.
+ ///
+ /// # Arguments
+ /// * rawpath - a string representing the path component of a URL.
+ ///
+ /// # Return value
+ ///
+ /// `Err(e)` if the string did not represent a valid URL path, where `e` is a
+ /// `String` error message. Otherwise, `Ok(p)` where `p` is a `Path` struct
+ /// representing the URL path.
+ pub fn parse(rawpath: &str) -> DecodeResult<Path> {
+ let (path, rest) = try!(get_path(rawpath, false));
+
+ // query and fragment
+ let (query, fragment) = try!(get_query_fragment(rest.as_slice()));
+
+ Ok(Path{ path: path, query: query, fragment: fragment })
+ }
+}
+
+#[deprecated="use `Path::parse`"]
+pub fn path_from_str(s: &str) -> Result<Path, String> {
+ Path::parse(s)
}
impl UserInfo {
}
}
-fn encode_inner(s: &str, full_url: bool) -> String {
- let mut rdr = BufReader::new(s.as_bytes());
- let mut out = String::new();
-
- loop {
- let mut buf = [0];
- let ch = match rdr.read(buf) {
- Err(..) => break,
- Ok(..) => buf[0] as char,
+fn encode_inner<T: BytesContainer>(c: T, full_url: bool) -> String {
+ c.container_as_bytes().iter().fold(String::new(), |mut out, &b| {
+ match b as char {
+ // unreserved:
+ 'A' .. 'Z'
+ | 'a' .. 'z'
+ | '0' .. '9'
+ | '-' | '.' | '_' | '~' => out.push_char(b as char),
+
+ // gen-delims:
+ ':' | '/' | '?' | '#' | '[' | ']' | '@' |
+ // sub-delims:
+ '!' | '$' | '&' | '"' | '(' | ')' | '*' |
+ '+' | ',' | ';' | '='
+ if full_url => out.push_char(b as char),
+
+ ch => out.push_str(format!("%{:02X}", ch as uint).as_slice()),
};
- match ch {
- // unreserved:
- 'A' .. 'Z' |
- 'a' .. 'z' |
- '0' .. '9' |
- '-' | '.' | '_' | '~' => {
- out.push_char(ch);
- }
- _ => {
- if full_url {
- match ch {
- // gen-delims:
- ':' | '/' | '?' | '#' | '[' | ']' | '@' |
-
- // sub-delims:
- '!' | '$' | '&' | '"' | '(' | ')' | '*' |
- '+' | ',' | ';' | '=' => {
- out.push_char(ch);
- }
-
- _ => out.push_str(format!("%{:02X}", ch as uint).as_slice())
- }
- } else {
- out.push_str(format!("%{:02X}", ch as uint).as_slice());
- }
- }
- }
- }
-
- out
+ out
+ })
}
-/**
- * Encodes a URI by replacing reserved characters with percent-encoded
- * character sequences.
- *
- * This function is compliant with RFC 3986.
- *
- * # Example
- *
- * ```rust
- * use url::encode;
- *
- * let url = encode("https://example.com/Rust (programming language)");
- * println!("{}", url); // https://example.com/Rust%20(programming%20language)
- * ```
- */
-pub fn encode(s: &str) -> String {
- encode_inner(s, true)
+/// Encodes a URI by replacing reserved characters with percent-encoded
+/// character sequences.
+///
+/// This function is compliant with RFC 3986.
+///
+/// # Example
+///
+/// ```rust
+/// use url::encode;
+///
+/// let url = encode("https://example.com/Rust (programming language)");
+/// println!("{}", url); // https://example.com/Rust%20(programming%20language)
+/// ```
+pub fn encode<T: BytesContainer>(container: T) -> String {
+ encode_inner(container, true)
}
-/**
- * Encodes a URI component by replacing reserved characters with percent-
- * encoded character sequences.
- *
- * This function is compliant with RFC 3986.
- */
-pub fn encode_component(s: &str) -> String {
- encode_inner(s, false)
+/// Encodes a URI component by replacing reserved characters with percent-
+/// encoded character sequences.
+///
+/// This function is compliant with RFC 3986.
+pub fn encode_component<T: BytesContainer>(container: T) -> String {
+ encode_inner(container, false)
}
-fn decode_inner(s: &str, full_url: bool) -> String {
- let mut rdr = BufReader::new(s.as_bytes());
- let mut out = String::new();
+pub type DecodeResult<T> = Result<T, String>;
- loop {
- let mut buf = [0];
- let ch = match rdr.read(buf) {
- Err(..) => break,
- Ok(..) => buf[0] as char
- };
- match ch {
- '%' => {
- let mut bytes = [0, 0];
- match rdr.read(bytes) {
- Ok(2) => {}
- _ => fail!() // FIXME: malformed url?
- }
- let ch = uint::parse_bytes(bytes, 16u).unwrap() as u8 as char;
-
- if full_url {
- // Only decode some characters:
- match ch {
- // gen-delims:
- ':' | '/' | '?' | '#' | '[' | ']' | '@' |
-
- // sub-delims:
- '!' | '$' | '&' | '"' | '(' | ')' | '*' |
- '+' | ',' | ';' | '=' => {
- out.push_char('%');
- out.push_char(bytes[0u] as char);
- out.push_char(bytes[1u] as char);
- }
-
- ch => out.push_char(ch)
- }
- } else {
- out.push_char(ch);
- }
- }
- ch => out.push_char(ch)
- }
- }
-
- out
-}
-
-/**
- * Decodes a percent-encoded string representing a URI.
- *
- * This will only decode escape sequences generated by `encode`.
- *
- * # Example
- *
- * ```rust
- * use url::decode;
- *
- * let url = decode("https://example.com/Rust%20(programming%20language)");
- * println!("{}", url); // https://example.com/Rust (programming language)
- * ```
- */
-pub fn decode(s: &str) -> String {
- decode_inner(s, true)
+/// Decodes a percent-encoded string representing a URI.
+///
+/// This will only decode escape sequences generated by `encode`.
+///
+/// # Example
+///
+/// ```rust
+/// use url::decode;
+///
+/// let url = decode("https://example.com/Rust%20(programming%20language)");
+/// println!("{}", url); // https://example.com/Rust (programming language)
+/// ```
+pub fn decode<T: BytesContainer>(container: T) -> DecodeResult<String> {
+ decode_inner(container, true)
}
-/**
- * Decode a string encoded with percent encoding.
- */
-pub fn decode_component(s: &str) -> String {
- decode_inner(s, false)
+/// Decode a string encoded with percent encoding.
+pub fn decode_component<T: BytesContainer>(container: T) -> DecodeResult<String> {
+ decode_inner(container, false)
}
-fn encode_plus(s: &str) -> String {
- let mut rdr = BufReader::new(s.as_bytes());
+fn decode_inner<T: BytesContainer>(c: T, full_url: bool) -> DecodeResult<String> {
let mut out = String::new();
+ let mut iter = c.container_as_bytes().iter().map(|&b| b);
loop {
- let mut buf = [0];
- let ch = match rdr.read(buf) {
- Ok(..) => buf[0] as char,
- Err(..) => break,
- };
- match ch {
- 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' | '.' | '-' => {
- out.push_char(ch);
- }
- ' ' => out.push_char('+'),
- _ => out.push_str(format!("%{:X}", ch as uint).as_slice())
+ match iter.next() {
+ Some(b) => match b as char {
+ '%' => {
+ let bytes = match (iter.next(), iter.next()) {
+ (Some(one), Some(two)) => [one as u8, two as u8],
+ _ => return Err(format!("Malformed input: found '%' \
+ without two trailing bytes")),
+ };
+
+ // Only decode some characters if full_url:
+ match uint::parse_bytes(bytes, 16u).unwrap() as u8 as char {
+ // gen-delims:
+ ':' | '/' | '?' | '#' | '[' | ']' | '@' |
+
+ // sub-delims:
+ '!' | '$' | '&' | '"' | '(' | ')' | '*' |
+ '+' | ',' | ';' | '='
+ if full_url => {
+ out.push_char('%');
+ out.push_char(bytes[0u] as char);
+ out.push_char(bytes[1u] as char);
+ }
+
+ ch => out.push_char(ch)
+ }
+ }
+ ch => out.push_char(ch)
+ },
+ None => return Ok(out),
}
}
-
- out
}
-/**
- * Encode a hashmap to the 'application/x-www-form-urlencoded' media type.
- */
+/// Encode a hashmap to the 'application/x-www-form-urlencoded' media type.
pub fn encode_form_urlencoded(m: &HashMap<String, Vec<String>>) -> String {
- let mut out = String::new();
- let mut first = true;
+ fn encode_plus<T: Str>(s: &T) -> String {
+ s.as_slice().bytes().fold(String::new(), |mut out, b| {
+ match b as char {
+ 'A' .. 'Z'
+ | 'a' .. 'z'
+ | '0' .. '9'
+ | '_' | '.' | '-' => out.push_char(b as char),
+ ' ' => out.push_char('+'),
+ ch => out.push_str(format!("%{:X}", ch as uint).as_slice())
+ }
+
+ out
+ })
+ }
- for (key, values) in m.iter() {
- let key = encode_plus(key.as_slice());
+ let mut first = true;
+ m.iter().fold(String::new(), |mut out, (key, values)| {
+ let key = encode_plus(key);
for value in values.iter() {
if first {
first = false;
} else {
out.push_char('&');
- first = false;
}
- out.push_str(format!("{}={}",
- key,
- encode_plus(value.as_slice())).as_slice());
+ out.push_str(key.as_slice());
+ out.push_char('=');
+ out.push_str(encode_plus(value).as_slice());
}
- }
- out
+ out
+ })
}
-/**
- * Decode a string encoded with the 'application/x-www-form-urlencoded' media
- * type into a hashmap.
- */
-#[allow(experimental)]
-pub fn decode_form_urlencoded(s: &[u8]) -> HashMap<String, Vec<String>> {
- let mut rdr = BufReader::new(s);
- let mut m: HashMap<String,Vec<String>> = HashMap::new();
+/// Decode a string encoded with the 'application/x-www-form-urlencoded' media
+/// type into a hashmap.
+pub fn decode_form_urlencoded(s: &[u8])
+ -> DecodeResult<HashMap<String, Vec<String>>> {
+ fn maybe_push_value(map: &mut HashMap<String, Vec<String>>,
+ key: String,
+ value: String) {
+ if key.len() > 0 && value.len() > 0 {
+ let values = map.find_or_insert_with(key, |_| vec!());
+ values.push(value);
+ }
+ }
+
+ let mut out = HashMap::new();
+ let mut iter = s.iter().map(|&x| x);
+
let mut key = String::new();
let mut value = String::new();
let mut parsing_key = true;
loop {
- let mut buf = [0];
- let ch = match rdr.read(buf) {
- Ok(..) => buf[0] as char,
- Err(..) => break,
- };
- match ch {
- '&' | ';' => {
- if key.len() > 0 && value.len() > 0 {
- let mut values = match m.pop_equiv(&key.as_slice()) {
- Some(values) => values,
- None => vec!(),
- };
-
- values.push(value);
- m.insert(key, values);
+ match iter.next() {
+ Some(b) => match b as char {
+ '&' | ';' => {
+ maybe_push_value(&mut out, key, value);
+
+ parsing_key = true;
+ key = String::new();
+ value = String::new();
}
-
- parsing_key = true;
- key = String::new();
- value = String::new();
- }
- '=' => parsing_key = false,
- ch => {
- let ch = match ch {
- '%' => {
- let mut bytes = [0, 0];
- match rdr.read(bytes) {
- Ok(2) => {}
- _ => fail!() // FIXME: malformed?
+ '=' => parsing_key = false,
+ ch => {
+ let ch = match ch {
+ '%' => {
+ let bytes = match (iter.next(), iter.next()) {
+ (Some(one), Some(two)) => [one as u8, two as u8],
+ _ => return Err(format!("Malformed input: found \
+ '%' without two trailing bytes"))
+ };
+
+ uint::parse_bytes(bytes, 16u).unwrap() as u8 as char
}
- uint::parse_bytes(bytes, 16u).unwrap() as u8 as char
- }
- '+' => ' ',
- ch => ch
- };
+ '+' => ' ',
+ ch => ch
+ };
- if parsing_key {
- key.push_char(ch)
- } else {
- value.push_char(ch)
+ if parsing_key {
+ key.push_char(ch)
+ } else {
+ value.push_char(ch)
+ }
}
+ },
+ None => {
+ maybe_push_value(&mut out, key, value);
+ return Ok(out)
}
}
}
-
- if key.len() > 0 && value.len() > 0 {
- let mut values = match m.pop_equiv(&key.as_slice()) {
- Some(values) => values,
- None => vec!(),
- };
-
- values.push(value);
- m.insert(key, values);
- }
-
- m
}
+fn split_char_first<'a>(s: &'a str, c: char) -> (&'a str, &'a str) {
+ let mut iter = s.splitn(c, 1);
-fn split_char_first(s: &str, c: char) -> (String, String) {
- let len = s.len();
- let mut index = len;
- let mut mat = 0;
- let mut rdr = BufReader::new(s.as_bytes());
- loop {
- let mut buf = [0];
- let ch = match rdr.read(buf) {
- Ok(..) => buf[0] as char,
- Err(..) => break,
- };
- if ch == c {
- // found a match, adjust markers
- index = (rdr.tell().unwrap() as uint) - 1;
- mat = 1;
- break;
- }
- }
- if index+mat == len {
- return (s.slice(0, index).to_string(), "".to_string());
- } else {
- return (s.slice(0, index).to_string(),
- s.slice(index + mat, s.len()).to_string());
+ match (iter.next(), iter.next()) {
+ (Some(a), Some(b)) => (a, b),
+ (Some(a), None) => (a, ""),
+ (None, _) => unreachable!(),
}
}
}
}
-fn query_from_str(rawquery: &str) -> Query {
+fn query_from_str(rawquery: &str) -> DecodeResult<Query> {
let mut query: Query = vec!();
if !rawquery.is_empty() {
for p in rawquery.split('&') {
let (k, v) = split_char_first(p, '=');
- query.push((decode_component(k.as_slice()),
- decode_component(v.as_slice())));
- };
+ query.push((try!(decode_component(k)),
+ try!(decode_component(v))));
+ }
}
- return query;
+
+ Ok(query)
}
-/**
- * Converts an instance of a URI `Query` type to a string.
- *
- * # Example
- *
- * ```rust
- * let query = vec!(("title".to_string(), "The Village".to_string()),
- * ("north".to_string(), "52.91".to_string()),
- * ("west".to_string(), "4.10".to_string()));
- * println!("{}", url::query_to_str(&query)); // title=The%20Village&north=52.91&west=4.10
- * ```
- */
-#[allow(unused_must_use)]
+/// Converts an instance of a URI `Query` type to a string.
+///
+/// # Example
+///
+/// ```rust
+/// let query = vec![("title".to_string(), "The Village".to_string()),
+/// ("north".to_string(), "52.91".to_string()),
+/// ("west".to_string(), "4.10".to_string())];
+/// println!("{}", url::query_to_str(&query)); // title=The%20Village&north=52.91&west=4.10
+/// ```
pub fn query_to_str(query: &Query) -> String {
- use std::io::MemWriter;
- use std::str;
-
- let mut writer = MemWriter::new();
- for (i, &(ref k, ref v)) in query.iter().enumerate() {
- if i != 0 { write!(&mut writer, "&"); }
- write!(&mut writer, "{}={}", encode_component(k.as_slice()),
- encode_component(v.as_slice()));
- }
- str::from_utf8_lossy(writer.unwrap().as_slice()).to_string()
+ query.iter().enumerate().fold(String::new(), |mut out, (i, &(ref k, ref v))| {
+ if i != 0 {
+ out.push_char('&');
+ }
+
+ out.push_str(encode_component(k.as_slice()).as_slice());
+ out.push_char('=');
+ out.push_str(encode_component(v.as_slice()).as_slice());
+ out
+ })
}
-/**
- * Returns a tuple of the URI scheme and the rest of the URI, or a parsing error.
- *
- * Does not include the separating `:` character.
- *
- * # Example
- *
- * ```rust
- * use url::get_scheme;
- *
- * let scheme = match get_scheme("https://example.com/") {
- * Ok((sch, _)) => sch,
- * Err(_) => "(None)".to_string(),
- * };
- * println!("Scheme in use: {}.", scheme); // Scheme in use: https.
- * ```
- */
-pub fn get_scheme(rawurl: &str) -> Result<(String, String), String> {
+/// Returns a tuple of the URI scheme and the rest of the URI, or a parsing error.
+///
+/// Does not include the separating `:` character.
+///
+/// # Example
+///
+/// ```rust
+/// use url::get_scheme;
+///
+/// let scheme = match get_scheme("https://example.com/") {
+/// Ok((sch, _)) => sch,
+/// Err(_) => "(None)",
+/// };
+/// println!("Scheme in use: {}.", scheme); // Scheme in use: https.
+/// ```
+pub fn get_scheme<'a>(rawurl: &'a str) -> DecodeResult<(&'a str, &'a str)> {
for (i,c) in rawurl.chars().enumerate() {
- match c {
- 'A' .. 'Z' | 'a' .. 'z' => continue,
- '0' .. '9' | '+' | '-' | '.' => {
- if i == 0 {
- return Err("url: Scheme must begin with a \
- letter.".to_string());
+ let result = match c {
+ 'A' .. 'Z'
+ | 'a' .. 'z' => continue,
+ '0' .. '9' | '+' | '-' | '.' => {
+ if i != 0 { continue }
+
+ Err("url: Scheme must begin with a letter.".to_string())
}
- continue;
- }
- ':' => {
- if i == 0 {
- return Err("url: Scheme cannot be empty.".to_string());
- } else {
- return Ok((rawurl.slice(0,i).to_string(),
- rawurl.slice(i+1,rawurl.len()).to_string()));
+ ':' => {
+ if i == 0 {
+ Err("url: Scheme cannot be empty.".to_string())
+ } else {
+ Ok((rawurl.slice(0,i), rawurl.slice(i+1,rawurl.len())))
+ }
}
- }
- _ => {
- return Err("url: Invalid character in scheme.".to_string());
- }
- }
- };
- return Err("url: Scheme must be terminated with a colon.".to_string());
-}
+ _ => Err("url: Invalid character in scheme.".to_string()),
+ };
-#[deriving(Clone, PartialEq)]
-enum Input {
- Digit, // all digits
- Hex, // digits and letters a-f
- Unreserved // all other legal characters
+ return result;
+ }
+
+ Err("url: Scheme must be terminated with a colon.".to_string())
}
// returns userinfo, host, port, and unparsed part, or an error
-fn get_authority(rawurl: &str) ->
- Result<(Option<UserInfo>, String, Option<String>, String), String> {
- if !rawurl.starts_with("//") {
- // there is no authority.
- return Ok((None, "".to_string(), None, rawurl.to_str()));
- }
-
+fn get_authority<'a>(rawurl: &'a str) ->
+ DecodeResult<(Option<UserInfo>, &'a str, Option<u16>, &'a str)> {
enum State {
Start, // starting state
PassHostPort, // could be in user or port
InPort // are in port
}
+ #[deriving(Clone, PartialEq)]
+ enum Input {
+ Digit, // all digits
+ Hex, // digits and letters a-f
+ Unreserved // all other legal characters
+ }
+
+ if !rawurl.starts_with("//") {
+ // there is no authority.
+ return Ok((None, "", None, rawurl));
+ }
+
let len = rawurl.len();
let mut st = Start;
let mut input = Digit; // most restricted, start here.
let mut userinfo = None;
- let mut host = "".to_string();
+ let mut host = "";
let mut port = None;
let mut colon_count = 0u;
let mut begin = 2;
let mut end = len;
- for (i,c) in rawurl.chars().enumerate() {
- if i < 2 { continue; } // ignore the leading //
-
+ for (i,c) in rawurl.chars().enumerate()
+ // ignore the leading '//' handled by early return
+ .skip(2) {
// deal with input class first
match c {
- '0' .. '9' => (),
- 'A' .. 'F' | 'a' .. 'f' => {
- if input == Digit {
- input = Hex;
+ '0' .. '9' => (),
+ 'A' .. 'F'
+ | 'a' .. 'f' => {
+ if input == Digit {
+ input = Hex;
+ }
}
- }
- 'G' .. 'Z' | 'g' .. 'z' | '-' | '.' | '_' | '~' | '%' |
- '&' |'\'' | '(' | ')' | '+' | '!' | '*' | ',' | ';' | '=' => {
- input = Unreserved;
- }
- ':' | '@' | '?' | '#' | '/' => {
- // separators, don't change anything
- }
- _ => {
- return Err("Illegal character in authority".to_string());
- }
+ 'G' .. 'Z'
+ | 'g' .. 'z'
+ | '-' | '.' | '_' | '~' | '%'
+ | '&' |'\'' | '(' | ')' | '+'
+ | '!' | '*' | ',' | ';' | '=' => input = Unreserved,
+ ':' | '@' | '?' | '#' | '/' => {
+ // separators, don't change anything
+ }
+ _ => return Err("Illegal character in authority".to_string()),
}
// now process states
pos = i;
if input == Unreserved {
// must be port
- host = rawurl.slice(begin, i).to_string();
+ host = rawurl.slice(begin, i);
st = InPort;
} else {
// can't be sure whether this is an ipv6 address or a port
}
Ip6Port => {
if input == Unreserved {
- return Err("Illegal characters in \
- authority.".to_string());
+ return Err("Illegal characters in authority.".to_string());
}
st = Ip6Host;
}
Ip6Host => {
if colon_count > 7 {
- host = rawurl.slice(begin, i).to_string();
+ host = rawurl.slice(begin, i);
pos = i;
st = InPort;
}
}
- _ => {
- return Err("Invalid ':' in authority.".to_string());
- }
+ _ => return Err("Invalid ':' in authority.".to_string()),
}
input = Digit; // reset input class
}
userinfo = Some(UserInfo::new(user, Some(pass)));
st = InHost;
}
- _ => {
- return Err("Invalid '@' in authority.".to_string());
- }
+ _ => return Err("Invalid '@' in authority.".to_string()),
}
begin = i+1;
}
// finish up
match st {
- Start => {
- host = rawurl.slice(begin, end).to_string();
- }
- PassHostPort | Ip6Port => {
+ Start => host = rawurl.slice(begin, end),
+ PassHostPort
+ | Ip6Port => {
if input != Digit {
return Err("Non-digit characters in port.".to_string());
}
- host = rawurl.slice(begin, pos).to_string();
- port = Some(rawurl.slice(pos+1, end).to_string());
- }
- Ip6Host | InHost => {
- host = rawurl.slice(begin, end).to_string();
+ host = rawurl.slice(begin, pos);
+ port = Some(rawurl.slice(pos+1, end));
}
+ Ip6Host
+ | InHost => host = rawurl.slice(begin, end),
InPort => {
if input != Digit {
return Err("Non-digit characters in port.".to_string());
}
- port = Some(rawurl.slice(pos+1, end).to_string());
+ port = Some(rawurl.slice(pos+1, end));
}
}
- let rest = rawurl.slice(end, len).to_string();
- return Ok((userinfo, host, port, rest));
+ let rest = rawurl.slice(end, len);
+ // If we have a port string, ensure it parses to u16.
+ let port = match port {
+ None => None,
+ opt => match opt.and_then(|p| FromStr::from_str(p)) {
+ None => return Err(format!("Failed to parse port: {}", port)),
+ opt => opt
+ }
+ };
+
+ Ok((userinfo, host, port, rest))
}
// returns the path and unparsed part of url, or an error
-fn get_path(rawurl: &str, authority: bool) ->
- Result<(String, String), String> {
+fn get_path<'a>(rawurl: &'a str, is_authority: bool)
+ -> DecodeResult<(String, &'a str)> {
let len = rawurl.len();
let mut end = len;
for (i,c) in rawurl.chars().enumerate() {
match c {
- 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '&' |'\'' | '(' | ')' | '.'
- | '@' | ':' | '%' | '/' | '+' | '!' | '*' | ',' | ';' | '='
- | '_' | '-' | '~' => {
- continue;
- }
+ 'A' .. 'Z'
+ | 'a' .. 'z'
+ | '0' .. '9'
+ | '&' |'\'' | '(' | ')' | '.'
+ | '@' | ':' | '%' | '/' | '+'
+ | '!' | '*' | ',' | ';' | '='
+ | '_' | '-' | '~' => continue,
'?' | '#' => {
end = i;
break;
}
}
- if authority {
- if end != 0 && !rawurl.starts_with("/") {
- return Err("Non-empty path must begin with\
- '/' in presence of authority.".to_string());
- }
+ if is_authority && end != 0 && !rawurl.starts_with("/") {
+ Err("Non-empty path must begin with \
+ '/' in presence of authority.".to_string())
+ } else {
+ Ok((try!(decode_component(rawurl.slice(0, end))),
+ rawurl.slice(end, len)))
}
-
- return Ok((decode_component(rawurl.slice(0, end)),
- rawurl.slice(end, len).to_string()));
}
// returns the parsed query and the fragment, if present
-fn get_query_fragment(rawurl: &str) ->
- Result<(Query, Option<String>), String> {
- if !rawurl.starts_with("?") {
- if rawurl.starts_with("#") {
- let f = decode_component(rawurl.slice(
- 1,
- rawurl.len()));
- return Ok((vec!(), Some(f)));
- } else {
- return Ok((vec!(), None));
- }
- }
- let (q, r) = split_char_first(rawurl.slice(1, rawurl.len()), '#');
- let f = if r.len() != 0 {
- Some(decode_component(r.as_slice()))
- } else {
- None
- };
- return Ok((query_from_str(q.as_slice()), f));
-}
-
-/**
- * Parses a URL, converting it from a string to `Url` representation.
- *
- * # Arguments
- *
- * `rawurl` - a string representing the full URL, including scheme.
- *
- * # Returns
- *
- * A `Url` struct type representing the URL.
- */
-pub fn from_str(rawurl: &str) -> Result<Url, String> {
- // scheme
- let (scheme, rest) = match get_scheme(rawurl) {
- Ok(val) => val,
- Err(e) => return Err(e),
- };
-
- // authority
- let (userinfo, host, port, rest) = match get_authority(rest.as_slice()) {
- Ok(val) => val,
- Err(e) => return Err(e),
- };
-
- // path
- let has_authority = host.len() > 0;
- let (path, rest) = match get_path(rest.as_slice(), has_authority) {
- Ok(val) => val,
- Err(e) => return Err(e),
- };
-
- // query and fragment
- let (query, fragment) = match get_query_fragment(rest.as_slice()) {
- Ok(val) => val,
- Err(e) => return Err(e),
- };
-
- Ok(Url::new(scheme, userinfo, host, port, path, query, fragment))
-}
-
-pub fn path_from_str(rawpath: &str) -> Result<Path, String> {
- let (path, rest) = match get_path(rawpath, false) {
- Ok(val) => val,
- Err(e) => return Err(e)
- };
+fn get_query_fragment(rawurl: &str) -> DecodeResult<(Query, Option<String>)> {
+ let (before_fragment, raw_fragment) = split_char_first(rawurl, '#');
- // query and fragment
- let (query, fragment) = match get_query_fragment(rest.as_slice()) {
- Ok(val) => val,
- Err(e) => return Err(e),
+ // Parse the fragment if available
+ let fragment = match raw_fragment {
+ "" => None,
+ raw => Some(try!(decode_component(raw)))
};
- Ok(Path{ path: path, query: query, fragment: fragment })
+ match before_fragment.slice_shift_char() {
+ (Some('?'), rest) => Ok((try!(query_from_str(rest)), fragment)),
+ (None, "") => Ok((vec!(), fragment)),
+ _ => Err(format!("Query didn't start with '?': '{}..'", before_fragment)),
+ }
}
impl FromStr for Url {
fn from_str(s: &str) -> Option<Url> {
- match from_str(s) {
- Ok(url) => Some(url),
- Err(_) => None
- }
+ Url::parse(s).ok()
}
}
impl FromStr for Path {
fn from_str(s: &str) -> Option<Path> {
- match path_from_str(s) {
- Ok(path) => Some(path),
- Err(_) => None
- }
+ Path::parse(s).ok()
}
}
impl fmt::Show for Url {
- /**
- * Converts a URL from `Url` to string representation.
- *
- * # Arguments
- *
- * `url` - a URL.
- *
- * # Returns
- *
- * A string that contains the formatted URL. Note that this will usually
- * be an inverse of `from_str` but might strip out unneeded separators;
- * for example, "http://somehost.com?", when parsed and formatted, will
- * result in just "http://somehost.com".
- */
+ /// Converts a URL from `Url` to string representation.
+ ///
+ /// # Returns
+ ///
+ /// A string that contains the formatted URL. Note that this will usually
+ /// be an inverse of `from_str` but might strip out unneeded separators;
+ /// for example, "http://somehost.com?", when parsed and formatted, will
+ /// result in just "http://somehost.com".
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "{}:", self.scheme));
}
}
- try!(write!(f, "{}", self.path));
-
- if !self.query.is_empty() {
- try!(write!(f, "?{}", query_to_str(&self.query)));
- }
-
- match self.fragment {
- Some(ref fragment) => {
- write!(f, "#{}", encode_component(fragment.as_slice()))
- }
- None => Ok(()),
- }
+ write!(f, "{}", self.path)
}
}
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "{}", self.path));
if !self.query.is_empty() {
- try!(write!(f, "?{}", self.query))
+ try!(write!(f, "?{}", query_to_str(&self.query)))
}
match self.fragment {
impl<S: hash::Writer> hash::Hash<S> for Url {
fn hash(&self, state: &mut S) {
- self.to_str().hash(state)
+ self.to_string().hash(state)
}
}
impl<S: hash::Writer> hash::Hash<S> for Path {
fn hash(&self, state: &mut S) {
- self.to_str().hash(state)
+ self.to_string().hash(state)
}
}
#[test]
fn test_split_char_first() {
let (u,v) = split_char_first("hello, sweet world", ',');
- assert_eq!(u, "hello".to_string());
- assert_eq!(v, " sweet world".to_string());
+ assert_eq!(u, "hello");
+ assert_eq!(v, " sweet world");
let (u,v) = split_char_first("hello sweet world", ',');
- assert_eq!(u, "hello sweet world".to_string());
- assert_eq!(v, "".to_string());
+ assert_eq!(u, "hello sweet world");
+ assert_eq!(v, "");
}
#[test]
let (u, h, p, r) = get_authority(
"//user:pass@rust-lang.org/something").unwrap();
assert_eq!(u, Some(UserInfo::new("user".to_string(), Some("pass".to_string()))));
- assert_eq!(h, "rust-lang.org".to_string());
+ assert_eq!(h, "rust-lang.org");
assert!(p.is_none());
- assert_eq!(r, "/something".to_string());
+ assert_eq!(r, "/something");
let (u, h, p, r) = get_authority(
"//rust-lang.org:8000?something").unwrap();
assert!(u.is_none());
- assert_eq!(h, "rust-lang.org".to_string());
- assert_eq!(p, Some("8000".to_string()));
- assert_eq!(r, "?something".to_string());
+ assert_eq!(h, "rust-lang.org");
+ assert_eq!(p, Some(8000));
+ assert_eq!(r, "?something");
- let (u, h, p, r) = get_authority(
- "//rust-lang.org#blah").unwrap();
+ let (u, h, p, r) = get_authority("//rust-lang.org#blah").unwrap();
assert!(u.is_none());
- assert_eq!(h, "rust-lang.org".to_string());
+ assert_eq!(h, "rust-lang.org");
assert!(p.is_none());
- assert_eq!(r, "#blah".to_string());
+ assert_eq!(r, "#blah");
// ipv6 tests
let (_, h, _, _) = get_authority(
"//2001:0db8:85a3:0042:0000:8a2e:0370:7334#blah").unwrap();
- assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334".to_string());
+ assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334");
let (_, h, p, _) = get_authority(
"//2001:0db8:85a3:0042:0000:8a2e:0370:7334:8000#blah").unwrap();
- assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334".to_string());
- assert_eq!(p, Some("8000".to_string()));
+ assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334");
+ assert_eq!(p, Some(8000));
let (u, h, p, _) = get_authority(
"//us:p@2001:0db8:85a3:0042:0000:8a2e:0370:7334:8000#blah"
).unwrap();
assert_eq!(u, Some(UserInfo::new("us".to_string(), Some("p".to_string()))));
- assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334".to_string());
- assert_eq!(p, Some("8000".to_string()));
+ assert_eq!(h, "2001:0db8:85a3:0042:0000:8a2e:0370:7334");
+ assert_eq!(p, Some(8000));
// invalid authorities;
assert!(get_authority("//user:pass@rust-lang:something").is_err());
"//2001:0db8:85a3:0042:0000:8a2e:0370:7334:800a").is_err());
assert!(get_authority(
"//2001:0db8:85a3:0042:0000:8a2e:0370:7334:8000:00").is_err());
+ // outside u16 range
+ assert!(get_authority("//user:pass@rust-lang:65536").is_err());
// these parse as empty, because they don't start with '//'
let (_, h, _, _) = get_authority("user:pass@rust-lang").unwrap();
- assert_eq!(h, "".to_string());
+ assert_eq!(h, "");
let (_, h, _, _) = get_authority("rust-lang.org").unwrap();
- assert_eq!(h, "".to_string());
+ assert_eq!(h, "");
}
#[test]
fn test_get_path() {
let (p, r) = get_path("/something+%20orother", true).unwrap();
assert_eq!(p, "/something+ orother".to_string());
- assert_eq!(r, "".to_string());
+ assert_eq!(r, "");
let (p, r) = get_path("test@email.com#fragment", false).unwrap();
assert_eq!(p, "test@email.com".to_string());
- assert_eq!(r, "#fragment".to_string());
+ assert_eq!(r, "#fragment");
let (p, r) = get_path("/gen/:addr=?q=v", false).unwrap();
assert_eq!(p, "/gen/:addr=".to_string());
- assert_eq!(r, "?q=v".to_string());
+ assert_eq!(r, "?q=v");
//failure cases
assert!(get_path("something?q", true).is_err());
#[cfg(test)]
mod tests {
- use {encode_form_urlencoded, decode_form_urlencoded,
- decode, encode, from_str, encode_component, decode_component,
- path_from_str, UserInfo, get_scheme};
+ use {encode_form_urlencoded, decode_form_urlencoded, decode, encode,
+ encode_component, decode_component, UserInfo, get_scheme, Url, Path};
use std::collections::HashMap;
+ use std::path::BytesContainer;
#[test]
fn test_url_parse() {
let url = "http://user:pass@rust-lang.org:8080/doc/~u?s=v#something";
-
- let up = from_str(url);
- let u = up.unwrap();
- assert_eq!(&u.scheme, &"http".to_string());
- assert_eq!(&u.user, &Some(UserInfo::new("user".to_string(), Some("pass".to_string()))));
- assert_eq!(&u.host, &"rust-lang.org".to_string());
- assert_eq!(&u.port, &Some("8080".to_string()));
- assert_eq!(&u.path, &"/doc/~u".to_string());
- assert_eq!(&u.query, &vec!(("s".to_string(), "v".to_string())));
- assert_eq!(&u.fragment, &Some("something".to_string()));
+ let u = from_str::<Url>(url).unwrap();
+
+ assert_eq!(u.scheme, "http".to_string());
+ assert_eq!(u.user, Some(UserInfo::new("user".to_string(), Some("pass".to_string()))));
+ assert_eq!(u.host, "rust-lang.org".to_string());
+ assert_eq!(u.port, Some(8080));
+ assert_eq!(u.path.path, "/doc/~u".to_string());
+ assert_eq!(u.path.query, vec!(("s".to_string(), "v".to_string())));
+ assert_eq!(u.path.fragment, Some("something".to_string()));
}
#[test]
fn test_path_parse() {
let path = "/doc/~u?s=v#something";
+ let u = from_str::<Path>(path).unwrap();
- let up = path_from_str(path);
- let u = up.unwrap();
- assert_eq!(&u.path, &"/doc/~u".to_string());
- assert_eq!(&u.query, &vec!(("s".to_string(), "v".to_string())));
- assert_eq!(&u.fragment, &Some("something".to_string()));
+ assert_eq!(u.path, "/doc/~u".to_string());
+ assert_eq!(u.query, vec!(("s".to_string(), "v".to_string())));
+ assert_eq!(u.fragment, Some("something".to_string()));
}
#[test]
fn test_url_parse_host_slash() {
let urlstr = "http://0.42.42.42/";
- let url = from_str(urlstr).unwrap();
- assert!(url.host == "0.42.42.42".to_string());
- assert!(url.path == "/".to_string());
+ let url = from_str::<Url>(urlstr).unwrap();
+ assert_eq!(url.host, "0.42.42.42".to_string());
+ assert_eq!(url.path.path, "/".to_string());
}
#[test]
fn test_path_parse_host_slash() {
let pathstr = "/";
- let path = path_from_str(pathstr).unwrap();
- assert!(path.path == "/".to_string());
+ let path = from_str::<Path>(pathstr).unwrap();
+ assert_eq!(path.path, "/".to_string());
}
#[test]
fn test_url_host_with_port() {
let urlstr = "scheme://host:1234";
- let url = from_str(urlstr).unwrap();
- assert_eq!(&url.scheme, &"scheme".to_string());
- assert_eq!(&url.host, &"host".to_string());
- assert_eq!(&url.port, &Some("1234".to_string()));
+ let url = from_str::<Url>(urlstr).unwrap();
+ assert_eq!(url.scheme, "scheme".to_string());
+ assert_eq!(url.host, "host".to_string());
+ assert_eq!(url.port, Some(1234));
// is empty path really correct? Other tests think so
- assert_eq!(&url.path, &"".to_string());
+ assert_eq!(url.path.path, "".to_string());
+
let urlstr = "scheme://host:1234/";
- let url = from_str(urlstr).unwrap();
- assert_eq!(&url.scheme, &"scheme".to_string());
- assert_eq!(&url.host, &"host".to_string());
- assert_eq!(&url.port, &Some("1234".to_string()));
- assert_eq!(&url.path, &"/".to_string());
+ let url = from_str::<Url>(urlstr).unwrap();
+ assert_eq!(url.scheme, "scheme".to_string());
+ assert_eq!(url.host, "host".to_string());
+ assert_eq!(url.port, Some(1234));
+ assert_eq!(url.path.path, "/".to_string());
}
#[test]
fn test_url_with_underscores() {
let urlstr = "http://dotcom.com/file_name.html";
- let url = from_str(urlstr).unwrap();
- assert!(url.path == "/file_name.html".to_string());
+ let url = from_str::<Url>(urlstr).unwrap();
+ assert_eq!(url.path.path, "/file_name.html".to_string());
}
#[test]
fn test_path_with_underscores() {
let pathstr = "/file_name.html";
- let path = path_from_str(pathstr).unwrap();
- assert!(path.path == "/file_name.html".to_string());
+ let path = from_str::<Path>(pathstr).unwrap();
+ assert_eq!(path.path, "/file_name.html".to_string());
}
#[test]
fn test_url_with_dashes() {
let urlstr = "http://dotcom.com/file-name.html";
- let url = from_str(urlstr).unwrap();
- assert!(url.path == "/file-name.html".to_string());
+ let url = from_str::<Url>(urlstr).unwrap();
+ assert_eq!(url.path.path, "/file-name.html".to_string());
}
#[test]
fn test_path_with_dashes() {
let pathstr = "/file-name.html";
- let path = path_from_str(pathstr).unwrap();
- assert!(path.path == "/file-name.html".to_string());
+ let path = from_str::<Path>(pathstr).unwrap();
+ assert_eq!(path.path, "/file-name.html".to_string());
}
#[test]
#[test]
fn test_invalid_scheme_errors() {
- assert!(from_str("99://something").is_err());
- assert!(from_str("://something").is_err());
+ assert!(Url::parse("99://something").is_err());
+ assert!(Url::parse("://something").is_err());
}
#[test]
fn test_full_url_parse_and_format() {
let url = "http://user:pass@rust-lang.org/doc?s=v#something";
- assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+ let u = from_str::<Url>(url).unwrap();
+ assert_eq!(format!("{}", u).as_slice(), url);
}
#[test]
fn test_userless_url_parse_and_format() {
let url = "http://rust-lang.org/doc?s=v#something";
- assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+ let u = from_str::<Url>(url).unwrap();
+ assert_eq!(format!("{}", u).as_slice(), url);
}
#[test]
fn test_queryless_url_parse_and_format() {
let url = "http://user:pass@rust-lang.org/doc#something";
- assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+ let u = from_str::<Url>(url).unwrap();
+ assert_eq!(format!("{}", u).as_slice(), url);
}
#[test]
fn test_empty_query_url_parse_and_format() {
let url = "http://user:pass@rust-lang.org/doc?#something";
let should_be = "http://user:pass@rust-lang.org/doc#something";
- assert_eq!(from_str(url).unwrap().to_str().as_slice(), should_be);
+ let u = from_str::<Url>(url).unwrap();
+ assert_eq!(format!("{}", u).as_slice(), should_be);
}
#[test]
fn test_fragmentless_url_parse_and_format() {
let url = "http://user:pass@rust-lang.org/doc?q=v";
- assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+ let u = from_str::<Url>(url).unwrap();
+ assert_eq!(format!("{}", u).as_slice(), url);
}
#[test]
fn test_minimal_url_parse_and_format() {
let url = "http://rust-lang.org/doc";
- assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+ let u = from_str::<Url>(url).unwrap();
+ assert_eq!(format!("{}", u).as_slice(), url);
}
#[test]
fn test_url_with_port_parse_and_format() {
let url = "http://rust-lang.org:80/doc";
- assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+ let u = from_str::<Url>(url).unwrap();
+ assert_eq!(format!("{}", u).as_slice(), url);
}
#[test]
fn test_scheme_host_only_url_parse_and_format() {
let url = "http://rust-lang.org";
- assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+ let u = from_str::<Url>(url).unwrap();
+ assert_eq!(format!("{}", u).as_slice(), url);
}
#[test]
fn test_pathless_url_parse_and_format() {
let url = "http://user:pass@rust-lang.org?q=v#something";
- assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+ let u = from_str::<Url>(url).unwrap();
+ assert_eq!(format!("{}", u).as_slice(), url);
}
#[test]
fn test_scheme_host_fragment_only_url_parse_and_format() {
let url = "http://rust-lang.org#something";
- assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+ let u = from_str::<Url>(url).unwrap();
+ assert_eq!(format!("{}", u).as_slice(), url);
}
#[test]
fn test_url_component_encoding() {
let url = "http://rust-lang.org/doc%20uments?ba%25d%20=%23%26%2B";
- let u = from_str(url).unwrap();
- assert!(u.path == "/doc uments".to_string());
- assert!(u.query == vec!(("ba%d ".to_string(), "#&+".to_string())));
+ let u = from_str::<Url>(url).unwrap();
+ assert!(u.path.path == "/doc uments".to_string());
+ assert!(u.path.query == vec!(("ba%d ".to_string(), "#&+".to_string())));
}
#[test]
fn test_path_component_encoding() {
let path = "/doc%20uments?ba%25d%20=%23%26%2B";
- let p = path_from_str(path).unwrap();
+ let p = from_str::<Path>(path).unwrap();
assert!(p.path == "/doc uments".to_string());
assert!(p.query == vec!(("ba%d ".to_string(), "#&+".to_string())));
}
#[test]
fn test_url_without_authority() {
let url = "mailto:test@email.com";
- assert_eq!(from_str(url).unwrap().to_str().as_slice(), url);
+ let u = from_str::<Url>(url).unwrap();
+ assert_eq!(format!("{}", u).as_slice(), url);
}
#[test]
fn test_encode() {
- assert_eq!(encode(""), "".to_string());
- assert_eq!(encode("http://example.com"), "http://example.com".to_string());
- assert_eq!(encode("foo bar% baz"), "foo%20bar%25%20baz".to_string());
- assert_eq!(encode(" "), "%20".to_string());
- assert_eq!(encode("!"), "!".to_string());
- assert_eq!(encode("\""), "\"".to_string());
- assert_eq!(encode("#"), "#".to_string());
- assert_eq!(encode("$"), "$".to_string());
- assert_eq!(encode("%"), "%25".to_string());
- assert_eq!(encode("&"), "&".to_string());
- assert_eq!(encode("'"), "%27".to_string());
- assert_eq!(encode("("), "(".to_string());
- assert_eq!(encode(")"), ")".to_string());
- assert_eq!(encode("*"), "*".to_string());
- assert_eq!(encode("+"), "+".to_string());
- assert_eq!(encode(","), ",".to_string());
- assert_eq!(encode("/"), "/".to_string());
- assert_eq!(encode(":"), ":".to_string());
- assert_eq!(encode(";"), ";".to_string());
- assert_eq!(encode("="), "=".to_string());
- assert_eq!(encode("?"), "?".to_string());
- assert_eq!(encode("@"), "@".to_string());
- assert_eq!(encode("["), "[".to_string());
- assert_eq!(encode("]"), "]".to_string());
- assert_eq!(encode("\0"), "%00".to_string());
- assert_eq!(encode("\n"), "%0A".to_string());
+ fn t<T: BytesContainer>(input: T, expected: &str) {
+ assert_eq!(encode(input), expected.to_string())
+ }
+
+ t("", "");
+ t("http://example.com", "http://example.com");
+ t("foo bar% baz", "foo%20bar%25%20baz");
+ t(" ", "%20");
+ t("!", "!");
+ t("\"", "\"");
+ t("#", "#");
+ t("$", "$");
+ t("%", "%25");
+ t("&", "&");
+ t("'", "%27");
+ t("(", "(");
+ t(")", ")");
+ t("*", "*");
+ t("+", "+");
+ t(",", ",");
+ t("/", "/");
+ t(":", ":");
+ t(";", ";");
+ t("=", "=");
+ t("?", "?");
+ t("@", "@");
+ t("[", "[");
+ t("]", "]");
+ t("\0", "%00");
+ t("\n", "%0A");
+
+ t(&[0u8, 10, 37], "%00%0A%25");
}
#[test]
fn test_encode_component() {
- assert_eq!(encode_component(""), "".to_string());
- assert!(encode_component("http://example.com") ==
- "http%3A%2F%2Fexample.com".to_string());
- assert!(encode_component("foo bar% baz") ==
- "foo%20bar%25%20baz".to_string());
- assert_eq!(encode_component(" "), "%20".to_string());
- assert_eq!(encode_component("!"), "%21".to_string());
- assert_eq!(encode_component("#"), "%23".to_string());
- assert_eq!(encode_component("$"), "%24".to_string());
- assert_eq!(encode_component("%"), "%25".to_string());
- assert_eq!(encode_component("&"), "%26".to_string());
- assert_eq!(encode_component("'"), "%27".to_string());
- assert_eq!(encode_component("("), "%28".to_string());
- assert_eq!(encode_component(")"), "%29".to_string());
- assert_eq!(encode_component("*"), "%2A".to_string());
- assert_eq!(encode_component("+"), "%2B".to_string());
- assert_eq!(encode_component(","), "%2C".to_string());
- assert_eq!(encode_component("/"), "%2F".to_string());
- assert_eq!(encode_component(":"), "%3A".to_string());
- assert_eq!(encode_component(";"), "%3B".to_string());
- assert_eq!(encode_component("="), "%3D".to_string());
- assert_eq!(encode_component("?"), "%3F".to_string());
- assert_eq!(encode_component("@"), "%40".to_string());
- assert_eq!(encode_component("["), "%5B".to_string());
- assert_eq!(encode_component("]"), "%5D".to_string());
- assert_eq!(encode_component("\0"), "%00".to_string());
- assert_eq!(encode_component("\n"), "%0A".to_string());
+ fn t<T: BytesContainer>(input: T, expected: &str) {
+ assert_eq!(encode_component(input), expected.to_string())
+ }
+
+ t("", "");
+ t("http://example.com", "http%3A%2F%2Fexample.com");
+ t("foo bar% baz", "foo%20bar%25%20baz");
+ t(" ", "%20");
+ t("!", "%21");
+ t("#", "%23");
+ t("$", "%24");
+ t("%", "%25");
+ t("&", "%26");
+ t("'", "%27");
+ t("(", "%28");
+ t(")", "%29");
+ t("*", "%2A");
+ t("+", "%2B");
+ t(",", "%2C");
+ t("/", "%2F");
+ t(":", "%3A");
+ t(";", "%3B");
+ t("=", "%3D");
+ t("?", "%3F");
+ t("@", "%40");
+ t("[", "%5B");
+ t("]", "%5D");
+ t("\0", "%00");
+ t("\n", "%0A");
+
+ t(&[0u8, 10, 37], "%00%0A%25");
}
#[test]
fn test_decode() {
- assert_eq!(decode(""), "".to_string());
- assert_eq!(decode("abc/def 123"), "abc/def 123".to_string());
- assert_eq!(decode("abc%2Fdef%20123"), "abc%2Fdef 123".to_string());
- assert_eq!(decode("%20"), " ".to_string());
- assert_eq!(decode("%21"), "%21".to_string());
- assert_eq!(decode("%22"), "%22".to_string());
- assert_eq!(decode("%23"), "%23".to_string());
- assert_eq!(decode("%24"), "%24".to_string());
- assert_eq!(decode("%25"), "%".to_string());
- assert_eq!(decode("%26"), "%26".to_string());
- assert_eq!(decode("%27"), "'".to_string());
- assert_eq!(decode("%28"), "%28".to_string());
- assert_eq!(decode("%29"), "%29".to_string());
- assert_eq!(decode("%2A"), "%2A".to_string());
- assert_eq!(decode("%2B"), "%2B".to_string());
- assert_eq!(decode("%2C"), "%2C".to_string());
- assert_eq!(decode("%2F"), "%2F".to_string());
- assert_eq!(decode("%3A"), "%3A".to_string());
- assert_eq!(decode("%3B"), "%3B".to_string());
- assert_eq!(decode("%3D"), "%3D".to_string());
- assert_eq!(decode("%3F"), "%3F".to_string());
- assert_eq!(decode("%40"), "%40".to_string());
- assert_eq!(decode("%5B"), "%5B".to_string());
- assert_eq!(decode("%5D"), "%5D".to_string());
+ fn t<T: BytesContainer>(input: T, expected: &str) {
+ assert_eq!(decode(input), Ok(expected.to_string()))
+ }
+
+ assert!(decode("sadsadsda%").is_err());
+ assert!(decode("waeasd%4").is_err());
+ t("", "");
+ t("abc/def 123", "abc/def 123");
+ t("abc%2Fdef%20123", "abc%2Fdef 123");
+ t("%20", " ");
+ t("%21", "%21");
+ t("%22", "%22");
+ t("%23", "%23");
+ t("%24", "%24");
+ t("%25", "%");
+ t("%26", "%26");
+ t("%27", "'");
+ t("%28", "%28");
+ t("%29", "%29");
+ t("%2A", "%2A");
+ t("%2B", "%2B");
+ t("%2C", "%2C");
+ t("%2F", "%2F");
+ t("%3A", "%3A");
+ t("%3B", "%3B");
+ t("%3D", "%3D");
+ t("%3F", "%3F");
+ t("%40", "%40");
+ t("%5B", "%5B");
+ t("%5D", "%5D");
+
+ t("%00%0A%25".as_bytes(), "\0\n%");
}
#[test]
fn test_decode_component() {
- assert_eq!(decode_component(""), "".to_string());
- assert_eq!(decode_component("abc/def 123"), "abc/def 123".to_string());
- assert_eq!(decode_component("abc%2Fdef%20123"), "abc/def 123".to_string());
- assert_eq!(decode_component("%20"), " ".to_string());
- assert_eq!(decode_component("%21"), "!".to_string());
- assert_eq!(decode_component("%22"), "\"".to_string());
- assert_eq!(decode_component("%23"), "#".to_string());
- assert_eq!(decode_component("%24"), "$".to_string());
- assert_eq!(decode_component("%25"), "%".to_string());
- assert_eq!(decode_component("%26"), "&".to_string());
- assert_eq!(decode_component("%27"), "'".to_string());
- assert_eq!(decode_component("%28"), "(".to_string());
- assert_eq!(decode_component("%29"), ")".to_string());
- assert_eq!(decode_component("%2A"), "*".to_string());
- assert_eq!(decode_component("%2B"), "+".to_string());
- assert_eq!(decode_component("%2C"), ",".to_string());
- assert_eq!(decode_component("%2F"), "/".to_string());
- assert_eq!(decode_component("%3A"), ":".to_string());
- assert_eq!(decode_component("%3B"), ";".to_string());
- assert_eq!(decode_component("%3D"), "=".to_string());
- assert_eq!(decode_component("%3F"), "?".to_string());
- assert_eq!(decode_component("%40"), "@".to_string());
- assert_eq!(decode_component("%5B"), "[".to_string());
- assert_eq!(decode_component("%5D"), "]".to_string());
+ fn t<T: BytesContainer>(input: T, expected: &str) {
+ assert_eq!(decode_component(input), Ok(expected.to_string()))
+ }
+
+ assert!(decode_component("asacsa%").is_err());
+ assert!(decode_component("acsas%4").is_err());
+ t("", "");
+ t("abc/def 123", "abc/def 123");
+ t("abc%2Fdef%20123", "abc/def 123");
+ t("%20", " ");
+ t("%21", "!");
+ t("%22", "\"");
+ t("%23", "#");
+ t("%24", "$");
+ t("%25", "%");
+ t("%26", "&");
+ t("%27", "'");
+ t("%28", "(");
+ t("%29", ")");
+ t("%2A", "*");
+ t("%2B", "+");
+ t("%2C", ",");
+ t("%2F", "/");
+ t("%3A", ":");
+ t("%3B", ";");
+ t("%3D", "=");
+ t("%3F", "?");
+ t("%40", "@");
+ t("%5B", "[");
+ t("%5D", "]");
+
+ t("%00%0A%25".as_bytes(), "\0\n%");
}
#[test]
let mut m = HashMap::new();
m.insert("foo bar".to_string(), vec!("abc".to_string(), "12 = 34".to_string()));
- assert!(encode_form_urlencoded(&m) ==
- "foo+bar=abc&foo+bar=12+%3D+34".to_string());
+ assert_eq!(encode_form_urlencoded(&m),
+ "foo+bar=abc&foo+bar=12+%3D+34".to_string());
}
#[test]
fn test_decode_form_urlencoded() {
- assert_eq!(decode_form_urlencoded([]).len(), 0);
+ assert_eq!(decode_form_urlencoded([]).unwrap().len(), 0);
let s = "a=1&foo+bar=abc&foo+bar=12+%3D+34".as_bytes();
- let form = decode_form_urlencoded(s);
+ let form = decode_form_urlencoded(s).unwrap();
assert_eq!(form.len(), 2);
assert_eq!(form.get(&"a".to_string()), &vec!("1".to_string()));
assert_eq!(form.get(&"foo bar".to_string()),
fn main() {
let uuid1 = Uuid::new_v4();
- println!("{}", uuid1.to_str());
+ println!("{}", uuid1.to_string());
}
```
*/
-#![crate_id = "uuid#0.11.0"]
+#![crate_name = "uuid"]
#![experimental]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
- html_root_url = "http://doc.rust-lang.org/0.11.0/",
+ html_root_url = "http://doc.rust-lang.org/master/",
html_playground_url = "http://play.rust-lang.org/")]
#![feature(default_type_params)]
// Round-trip
let uuid_orig = Uuid::new_v4();
- let orig_str = uuid_orig.to_str();
+ let orig_str = uuid_orig.to_string();
let uuid_out = Uuid::parse_string(orig_str.as_slice()).unwrap();
assert!(uuid_orig == uuid_out);
}
#[test]
- fn test_to_str() {
+ fn test_to_string() {
let uuid1 = Uuid::new_v4();
- let s = uuid1.to_str();
+ let s = uuid1.to_string();
assert!(s.len() == 32);
assert!(s.as_slice().chars().all(|c| c.is_digit_radix(16)));
let uuid1 = Uuid::new_v4();
let hs = uuid1.to_hyphenated_str();
- let ss = uuid1.to_str();
+ let ss = uuid1.to_string();
let hsn = str::from_chars(hs.as_slice()
.chars()
let uuid_hs = Uuid::parse_string(hs.as_slice()).unwrap();
assert!(uuid_hs == uuid);
- let ss = uuid.to_str();
+ let ss = uuid.to_string();
let uuid_ss = Uuid::parse_string(ss.as_slice()).unwrap();
assert!(uuid_ss == uuid);
}
}
#[bench]
- pub fn uuid_to_str(b: &mut Bencher) {
+ pub fn uuid_to_string(b: &mut Bencher) {
let u = Uuid::new_v4();
b.iter(|| {
- u.to_str();
+ u.to_string();
})
}
+S 2014-07-09 8ddd286
+ freebsd-x86_64 de0c39057f409b69e5ddb888ba3e20b90d63f5db
+ linux-i386 28bef31f2a017e1998256d0c2b2e0a0c9221451b
+ linux-x86_64 853bd73501a10d49cafdf823110c61f13a3392d6
+ macos-i386 b89540ae54f9e565565d36147a586bb4bfbd861b
+ macos-x86_64 58709eb936e7fd66a28a1bb82aaf43a4d8260dea
+ winnt-i386 64a32dcb008d4590a6c6a9efaffbe1d22a334d34
+
+S 2014-07-05 aaff4e0
+ freebsd-x86_64 10272ca9eb17e1be4a4b172aacfb4b33fffcc8fb
+ linux-i386 72ba9f6e0d096c30f128cb3736ffac0b57530a20
+ linux-x86_64 e5621f84934a7d76002ab95a354fbbb9ae6ebbb1
+ macos-i386 a88fd84ee959e59265de12b8f551ed56c0e943df
+ macos-x86_64 f19d479e5a0d2a6067a05b1910e4a6a544836b0a
+ winnt-i386 0c5a91e422409b89ac22f8c265af66f759d476c8
+
S 2014-06-25 bab614f
freebsd-x86_64 14cb361c8fdefa2534bb6776a04815c08680ecd6
linux-i386 8fec4845626c557431a4aa7bfb2b5cfc65ad9eda
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![crate_id="crateresolve1#0.1"]
-
+// compile-flags:-C extra-filename=-1
+#![crate_name = "crateresolve1"]
#![crate_type = "lib"]
pub fn f() -> int { 10 }
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![crate_id="crateresolve1#0.2"]
-
+// compile-flags:-C extra-filename=-2
+#![crate_name = "crateresolve1"]
#![crate_type = "lib"]
pub fn f() -> int { 20 }
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![crate_id="crateresolve1#0.3"]
-
+// compile-flags:-C extra-filename=-3
+#![crate_name = "crateresolve1"]
#![crate_type = "lib"]
pub fn f() -> int { 30 }
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_id="crateresolve2#0.1"]
-
-#![crate_type = "lib"]
-
-pub fn f() -> int { 10 }
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_id="crateresolve2#0.2"]
-
-#![crate_type = "lib"]
-
-pub fn f() -> int { 20 }
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_id="crateresolve2#0.3"]
-
-#![crate_type = "lib"]
-
-pub fn f() -> int { 30 }
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![crate_id="externcallback#0.1"]
+#![crate_name="externcallback"]
#![crate_type = "lib"]
extern crate libc;
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// no-prefer-dynamic
-
-#![crate_id = "url#0.11.0"]
-#![crate_type = "dylib"]
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// no-prefer-dynamic
-
-#![crate_id = "url#0.11.0"]
-#![crate_type = "rlib"]
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_type = "lib"]
-
-pub enum maybe<T> { just(T), nothing }
-
-impl <T:Clone> Index<uint,T> for maybe<T> {
- fn index(&self, _idx: &uint) -> T {
- match self {
- &just(ref t) => (*t).clone(),
- ¬hing => { fail!(); }
- }
- }
-}
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![crate_type = "lib"]
-
-extern crate issue2378a;
-
-use issue2378a::maybe;
-
-pub struct two_maybes<T> {pub a: maybe<T>, pub b: maybe<T>}
-
-impl<T:Clone> Index<uint,(T,T)> for two_maybes<T> {
- fn index(&self, idx: &uint) -> (T, T) {
- (self.a[*idx], self.b[*idx])
- }
-}
--- /dev/null
+// Copyright 2013-2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+#![feature(plugin_registrar)]
+
+extern crate rustc;
+
+use rustc::plugin::Registry;
+
+#[plugin_registrar]
+pub fn plugin_registrar(_: &mut Registry) {}
--- /dev/null
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub struct S {
+ pub x: int,
+ pub y: int,
+}
+
+pub type S2 = S;
+
let mut set = f();
timed(&mut self.sequential_strings, || {
for i in range(0u, num_keys) {
- set.insert(i.to_str());
+ set.insert(i.to_string());
}
for i in range(0u, num_keys) {
- assert!(set.contains(&i.to_str()));
+ assert!(set.contains(&i.to_string()));
}
})
}
let mut set = f();
timed(&mut self.random_strings, || {
for _ in range(0, num_keys) {
- let s = rng.gen::<uint>().to_str();
+ let s = rng.gen::<uint>().to_string();
set.insert(s);
}
})
{
let mut set = f();
for i in range(0u, num_keys) {
- set.insert(i.to_str());
+ set.insert(i.to_string());
}
timed(&mut self.delete_strings, || {
for i in range(0u, num_keys) {
- assert!(set.remove(&i.to_str()));
+ assert!(set.remove(&i.to_string()));
}
})
}
let n = from_str::<uint>(args.get(1).as_slice()).unwrap();
for i in range(0u, n) {
- let x = i.to_str();
+ let x = i.to_string();
println!("{}", x);
}
}
let mut out = String::new();
for col in set.iter() {
out.push_char(' ');
- out.push_str(col.to_str().as_slice());
+ out.push_str(col.to_string().as_slice());
}
out
}
k.as_slice()
.to_ascii()
.to_upper()
- .into_str(), v).as_slice());
+ .into_string(), v).as_slice());
}
return buffer
// given a map, search for the frequency of a pattern
fn find(mm: &HashMap<Vec<u8> , uint>, key: String) -> uint {
- let key = key.to_owned().into_ascii().as_slice().to_lower().into_str();
+ let key = key.to_owned().into_ascii().as_slice().to_lower().into_string();
match mm.find_equiv(&key.as_bytes()) {
option::None => { return 0u; }
option::Some(&num) => { return num; }
let elapsed = stop - start;
- println!("{}\t{}\t{}", n, fibn, elapsed.to_str());
+ println!("{}\t{}\t{}", n, fibn, elapsed.to_string());
}
}
}
} else {
box io::stdin() as Box<io::Reader>
};
- let mut seq = rdr.read_to_str().unwrap();
+ let mut seq = rdr.read_to_string().unwrap();
let ilen = seq.len();
seq = regex!(">[^\n]*\n|\n").replace_all(seq.as_slice(), NoExpand(""));
let (mut variant_strs, mut counts) = (vec!(), vec!());
for variant in variants.move_iter() {
let seq_arc_copy = seq_arc.clone();
- variant_strs.push(variant.to_str().to_owned());
+ variant_strs.push(variant.to_string().to_owned());
counts.push(Future::spawn(proc() {
count_matches(seq_arc_copy.as_slice(), &variant)
}));
--- /dev/null
+// Copyright 2013-2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:rlib_crate_test.rs
+// ignore-stage1
+// ignore-tidy-linelength
+// ignore-android
+
+#![feature(phase)]
+#[phase(plugin)] extern crate rlib_crate_test;
+//~^ ERROR: plugin crate `rlib_crate_test` only found in rlib format, but must be available in dylib format
+
+fn main() {}
extern crate macro_crate_test;
fn main() {
- assert_eq!(3, unexported_macro!()); //~ ERROR macro undefined: 'unexported_macro'
+ assert_eq!(3, unexported_macro!()); //~ ERROR macro undefined: 'unexported_macro!'
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-extern crate foo = ""; //~ ERROR: malformed crate id
-extern crate bar = "#a"; //~ ERROR: malformed crate id
+extern crate foo = ""; //~ ERROR: crate name must not be empty
fn main() {}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate bar = "#a"; //~ ERROR: invalid character `#` in crate name: `#a`
+
+fn main() {}
+
static STATIC2: Unsafe<int> = Unsafe{value: 1, marker1: marker::InvariantType};
static STATIC3: MyUnsafe<int> = MyUnsafe{value: STATIC2};
-static STATIC4: &'static Unsafe<int> = &'static STATIC2;
+static STATIC4: &'static Unsafe<int> = &STATIC2;
//~^ ERROR borrow of immutable static items with unsafe interior is not allowed
struct Wrap<T> {
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo {
+ x: int,
+ y: int,
+}
+
+impl Index<String,int> for Foo {
+ fn index<'a>(&'a self, z: &String) -> &'a int {
+ if z.as_slice() == "x" {
+ &self.x
+ } else {
+ &self.y
+ }
+ }
+}
+
+impl IndexMut<String,int> for Foo {
+ fn index_mut<'a>(&'a mut self, z: &String) -> &'a mut int {
+ if z.as_slice() == "x" {
+ &mut self.x
+ } else {
+ &mut self.y
+ }
+ }
+}
+
+struct Bar {
+ x: int,
+}
+
+impl Index<int,int> for Bar {
+ fn index<'a>(&'a self, z: &int) -> &'a int {
+ &self.x
+ }
+}
+
+fn main() {
+ let mut f = Foo {
+ x: 1,
+ y: 2,
+ };
+ let mut s = "hello".to_string();
+ let rs = &mut s;
+ println!("{}", f[s]);
+ //~^ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable
+ f[s] = 10;
+ //~^ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable
+ let s = Bar {
+ x: 1,
+ };
+ s[2] = 20;
+ //~^ ERROR cannot assign to immutable indexed content
+}
+
+
field2: Variant4("str".to_string())
};
-static STATIC15: &'static [Box<MyOwned>] = &'static [box MyOwned, box MyOwned];
+static STATIC15: &'static [Box<MyOwned>] = &[box MyOwned, box MyOwned];
//~^ ERROR static items are not allowed to have custom pointers
//~^^ ERROR static items are not allowed to have custom pointers
static STATIC16: (&'static Box<MyOwned>, &'static Box<MyOwned>) =
- (&'static box MyOwned, &'static box MyOwned);
+ (&box MyOwned, &box MyOwned);
//~^ ERROR static items are not allowed to have custom pointers
//~^^ ERROR static items are not allowed to have custom pointers
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve2-1.rs
-// aux-build:crateresolve2-2.rs
-// aux-build:crateresolve2-3.rs
-// error-pattern:using multiple versions of crate `crateresolve2`
-
-extern crate crateresolve2 = "crateresolve2#0.1";
-
-mod m {
- pub extern crate crateresolve2 = "crateresolve2#0.2";
-}
-
-fn main() {
- let x: int = false;
-}
+++ /dev/null
-// Copyright 2012-2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve5-1.rs
-// aux-build:crateresolve5-2.rs
-
-extern crate cr5_1 = "crateresolve5#0.1";
-extern crate cr5_2 = "crateresolve5#0.2";
-
-
-fn main() {
- // Nominal types from two multiple versions of a crate are different types
- assert!(cr5_1::nominal() == cr5_2::nominal()); //~ ERROR mismatched types: expected
-}
#![feature(struct_variant)]
enum Foo { C { a: int, b: int } }
-struct C { a: int, b: int } //~ ERROR error: duplicate definition of type `C`
+struct C { a: int, b: int } //~ ERROR error: duplicate definition of type or module `C`
struct A { x: int }
-enum Bar { A { x: int } } //~ ERROR error: duplicate definition of type `A`
+enum Bar { A { x: int } } //~ ERROR error: duplicate definition of type or module `A`
fn main() {}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod Foo {
+ pub static X: int = 42;
+}
+
+enum Foo { //~ ERROR duplicate definition of type or module `Foo`
+ X
+}
+
+fn main() {}
fn main() {
print!(test!());
- //~^ ERROR: macro undefined: 'test'
+ //~^ ERROR: macro undefined: 'test!'
//~^^ ERROR: format argument must be a string literal
concat!(test!());
- //~^ ERROR: macro undefined: 'test'
+ //~^ ERROR: macro undefined: 'test!'
}
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:issue-11908-1.rs
-// ignore-android this test is incompatible with the android test runner
-// error-pattern: multiple dylib candidates for `url` found
-
-// This test ensures that if you have the same rlib or dylib at two locations
-// in the same path that you don't hit an assertion in the compiler.
-//
-// Note that this relies on `liburl` to be in the path somewhere else,
-// and then our aux-built libraries will collide with liburl (they have
-// the same version listed)
-
-extern crate url;
-
-fn main() {}
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:issue-11908-2.rs
-// no-prefer-dynamic
-// ignore-android this test is incompatible with the android test runner
-// error-pattern: multiple rlib candidates for `url` found
-
-// see comments in issue-11908-1 for what's going on here
-
-extern crate url;
-
-fn main() {}
-
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn new<T>() -> &'static T {
+ fail!()
+}
+
+fn main() {
+ let &v = new();
+ //~^ ERROR cannot determine a type for this local variable: unconstrained type
+}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn new<'r, T>() -> &'r T {
+ fail!()
+}
+
+fn main() {
+ let &v = new();
+ //~^ ERROR cannot determine a type for this local variable: unconstrained type
+}
fn make(v: vec2) {
let vec3 { y: _, z: _ } = v;
- //~^ ERROR mismatched types: expected `vec2` but found `vec3`
+ //~^ ERROR `vec3` does not name the structure `vec2`
//~^^ ERROR struct `vec2` does not have a field named `z`
}
-fn main() { }
\ No newline at end of file
+fn main() { }
struct t(Box<t>); //~ ERROR this type cannot be instantiated
trait to_str_2 {
- fn my_to_str() -> String;
+ fn my_to_string() -> String;
}
// I use an impl here because it will cause
// the compiler to attempt autoderef and then
// try to resolve the method.
impl to_str_2 for t {
- fn my_to_str() -> String { "t".to_string() }
+ fn my_to_string() -> String { "t".to_string() }
}
fn new_t(x: t) {
- x.my_to_str(); //~ ERROR does not implement
+ x.my_to_string(); //~ ERROR does not implement
}
fn main() {
enum a { b, c }
-enum a { d, e } //~ ERROR duplicate definition of type `a`
+enum a { d, e } //~ ERROR duplicate definition of type or module `a`
fn main() {}
pub mod a {}
-pub mod a {} //~ ERROR duplicate definition of module `a`
+pub mod a {} //~ ERROR duplicate definition of type or module `a`
fn main() {}
y: f64,
}
-trait NewTrait {
- fn a(&self) -> String;
+trait ToString_ {
+ fn to_string(&self) -> String;
}
-impl NewTrait for Point {
+impl ToString_ for Point {
fn new(x: f64, y: f64) -> Point {
- //~^ ERROR method `new` is not a member of trait `NewTrait`
+ //~^ ERROR method `new` is not a member of trait `ToString_`
Point { x: x, y: y }
}
- fn a(&self) -> String {
+ fn to_string(&self) -> String {
format!("({}, {})", self.x, self.y)
}
}
let p = Point::new(0.0, 0.0);
//~^ ERROR unresolved name `Point::new`
//~^^ ERROR failed to resolve. Use of undeclared module `Point`
- println!("{}", p.a());
+ println!("{}", p.to_string());
}
--- /dev/null
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+static c: char =
+ '\u539_' //~ ERROR: illegal character in numeric character escape
+;
+
+static c2: char =
+ '\Uffffffff' //~ ERROR: illegal numeric character escape
+;
+
+static c3: char =
+ '\x1' //~ ERROR: numeric character escape is too short
+;
+
+static c4: char =
+ '\u23q' //~ ERROR: illegal character in numeric character escape
+;
+//~^^ ERROR: numeric character escape is too short
+
+static s: &'static str =
+ "\x1" //~ ERROR: numeric character escape is too short
+;
+
+static s2: &'static str =
+ "\u23q" //~ ERROR: illegal character in numeric character escape
+ //~^ ERROR: numeric character escape is too short
+;
+
+static c: char =
+ '\●' //~ ERROR: unknown character escape
+;
+
+static s: &'static str =
+ "\●" //~ ERROR: unknown character escape
+;
+
+// THIS MUST BE LAST, since unterminated character constants kill the lexer
+
+static c: char =
+ '● //~ ERROR: unterminated character constant
+;
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
- let a = 0o1.0; //~ ERROR: octal float literal is not supported
-}
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
- let b = 0o2f32; //~ ERROR: octal float literal is not supported
-}
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
- let c = 0o3.0f32; //~ ERROR: octal float literal is not supported
-}
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
- let d = 0o4e4; //~ ERROR: octal float literal is not supported
-}
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
- let e = 0o5.0e5; //~ ERROR: octal float literal is not supported
-}
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
- let f = 0o6e6f32; //~ ERROR: octal float literal is not supported
-}
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
- let g = 0o7.0e7f64; //~ ERROR: octal float literal is not supported
-}
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
- let h = 0x8.0e+9; //~ ERROR: hexadecimal float literal is not supported
-}
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
- let i = 0x9.0e-9; //~ ERROR: hexadecimal float literal is not supported
-}
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static f: float =
- 1e+ //~ ERROR: scan_exponent: bad fp literal
-;
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+ 0o1.0; //~ ERROR: octal float literal is not supported
+ 0o2f32; //~ ERROR: octal float literal is not supported
+ 0o3.0f32; //~ ERROR: octal float literal is not supported
+ 0o4e4; //~ ERROR: octal float literal is not supported
+ 0o5.0e5; //~ ERROR: octal float literal is not supported
+ 0o6e6f32; //~ ERROR: octal float literal is not supported
+ 0o7.0e7f64; //~ ERROR: octal float literal is not supported
+ 0x8.0e+9; //~ ERROR: hexadecimal float literal is not supported
+ 0x9.0e-9; //~ ERROR: hexadecimal float literal is not supported
+ 0o; //~ ERROR: no valid digits
+ 1e+; //~ ERROR: expected at least one digit in exponent
+ 0x539.0; //~ ERROR: hexadecimal float literal is not supported
+ 99999999999999999999999999999999; //~ ERROR: int literal is too large
+ 99999999999999999999999999999999u32; //~ ERROR: int literal is too large
+ 0x; //~ ERROR: no valid digits
+ 0xu32; //~ ERROR: no valid digits
+ 0ou32; //~ ERROR: no valid digits
+ 0bu32; //~ ERROR: no valid digits
+ 0b; //~ ERROR: no valid digits
+ 0o123f64; //~ ERROR: octal float literal is not supported
+ 0o123.456; //~ ERROR: octal float literal is not supported
+ 0b101f64; //~ ERROR: binary float literal is not supported
+ 0b111.101; //~ ERROR: binary float literal is not supported
+}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+● //~ ERROR: unknown start of token
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static f: float =
- 0x539.0 //~ ERROR: hexadecimal float literal is not supported
-;
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static c: char =
- '\u539_' //~ ERROR: illegal character in numeric character escape
-;
-
-static c2: char =
- '\Uffffffff' //~ ERROR: illegal numeric character escape
-;
-
-static c3: char =
- '\x1' //~ ERROR: numeric character escape is too short
-;
-
-static c4: char =
- '\u23q' //~ ERROR: illegal character in numeric character escape
-;
-//~^^ ERROR: numeric character escape is too short
-
-static s: &'static str =
- "\x1" //~ ERROR: numeric character escape is too short
-;
-
-static s2: &'static str =
- "\u23q" //~ ERROR: illegal character in numeric character escape
-;
-//~^^ ERROR: numeric character escape is too short
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static i: int =
- 99999999999999999999999999999999u32 //~ ERROR: int literal is too large
-;
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static i: int =
- 99999999999999999999999999999999 //~ ERROR: int literal is too large
-;
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static i: int =
- 0xu32 //~ ERROR: no valid digits
-;
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static i: int =
- 0x //~ ERROR: no valid digits
-;
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static c: char =
- '\●' //~ ERROR: unknown character escape
-;
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
- ● //~ ERROR: unknown start of token
-}
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static s: &'static str =
- "\●" //~ ERROR: unknown character escape
-;
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-static c: char =
- '● //~ ERROR: unterminated character constant
-;
trait foo6 { //~ ERROR trait `foo6` should have a camel case name such as `Foo6`
}
+#[repr(C)]
+struct foo7 {
+ bar: int,
+}
+
fn main() { }
let x = -2147483648_i32; // should be OK
let x: i32 = -2147483649; //~ error: literal out of range for its type
let x = -2147483649_i32; //~ error: literal out of range for its type
+
+ let x = -3.40282348e+38_f32; //~ error: literal out of range for its type
+ let x = 3.40282348e+38_f32; //~ error: literal out of range for its type
+ let x = -1.7976931348623159e+308_f64; //~ error: literal out of range for its type
+ let x = 1.7976931348623159e+308_f64; //~ error: literal out of range for its type
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+// ignore-tidy-linelength
+
#![allow(dead_code)]
#![deny(uppercase_variables)]
let mut buff = [0u8, ..16];
match f.read(buff) {
Ok(cnt) => println!("read this many bytes: {}", cnt),
- Err(IoError{ kind: EndOfFile, .. }) => println!("Got end of file: {}", EndOfFile.to_str()),
+ Err(IoError{ kind: EndOfFile, .. }) => println!("Got end of file: {}", EndOfFile.to_string()),
//~^ ERROR variable names should start with a lowercase character
}
fn main() {
let a: Vec<int> = Vec::new();
- a.iter().advance(|_| -> bool {
+ a.iter().all(|_| -> bool {
//~^ ERROR mismatched types
});
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+// ignore-tidy-linelength
struct S {
x: Box<E>
f(&s, |hellothere| {
match hellothere.x { //~ ERROR cannot move out
box Foo(_) => {}
- box Bar(x) => println!("{}", x.to_str()), //~ NOTE attempting to move value to here
+ box Bar(x) => println!("{}", x.to_string()), //~ NOTE attempting to move value to here
box Baz => {}
}
})
y: int
}
-impl Cmp, ToStr for S { //~ ERROR: expected `{` but found `,`
+impl Cmp, ToString for S { //~ ERROR: expected `{` but found `,`
fn eq(&&other: S) { false }
- fn to_str(&self) -> String { "hi".to_string() }
+ fn to_string(&self) -> String { "hi".to_string() }
}
// Tests that the new `box` syntax works with unique pointers and GC pointers.
use std::gc::{Gc, GC};
-use std::owned::{Box, HEAP};
+use std::boxed::{Box, HEAP};
pub fn main() {
let x: Gc<int> = box(HEAP) 2; //~ ERROR mismatched types
impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
- impl ToStr for Test {} //~ ERROR: attempt to implement a nonexistent trait
+ impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait
impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
fn foo() {
impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
- impl ToStr for Test {} //~ ERROR: attempt to implement a nonexistent trait
+ impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait
impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
fn foo() {
impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
- impl ToStr for Test {} //~ ERROR: attempt to implement a nonexistent trait
+ impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait
impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
fn foo() {
impl Add for Test {} //~ ERROR: attempt to implement a nonexistent trait
impl Clone for Test {} //~ ERROR: attempt to implement a nonexistent trait
impl Iterator for Test {} //~ ERROR: attempt to implement a nonexistent trait
-impl ToStr for Test {} //~ ERROR: attempt to implement a nonexistent trait
+impl ToString for Test {} //~ ERROR: attempt to implement a nonexistent trait
impl Writer for Test {} //~ ERROR: attempt to implement a nonexistent trait
fn main() {
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern:octal float literal is not supported
-
-fn main() {
- 0o123f64;
- 0o123.456;
- 0o123p4f;
-}
fn struct_with_a_nested_enum_and_vector() {
match (Foo { first: true, second: None }) {
- //~^ ERROR non-exhaustive patterns: `Foo{first: false, second: Some([_, _, _, _])}` not covered
+//~^ ERROR non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered
Foo { first: true, second: None } => (),
Foo { first: true, second: Some(_) } => (),
Foo { first: false, second: None } => (),
fn enum_struct_variant() {
match Red {
- //~^ ERROR non-exhaustive patterns: `CustomRGBA{a: true, r: _, g: _, b: _}` not covered
+ //~^ ERROR non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered
Red => (),
Green => (),
CustomRGBA { a: false, r: _, g: _, b: 0 } => (),
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(rustc_diagnostic_macros)]
+
+__register_diagnostic!(E0001)
+__register_diagnostic!(E0003)
+
+fn main() {
+ __diagnostic_used!(E0002);
+ //~^ ERROR unknown diagnostic code E0002
+
+ __diagnostic_used!(E0001);
+ //~^ NOTE previous invocation
+
+ __diagnostic_used!(E0001);
+ //~^ WARNING diagnostic code E0001 already used
+}
+
+__build_diagnostic_array!(DIAGNOSTICS)
+//~^ WARN diagnostic code E0003 never used
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(rustc_diagnostic_macros)]
+
+__register_diagnostic!(E0001)
+__register_diagnostic!(E0001)
+//~^ ERROR diagnostic code E0001 already registered
+
+fn main() {
+}
+
+__build_diagnostic_array!(DIAGNOSTICS)
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+__register_diagnostic!(E0001)
+//~^ ERROR macro undefined: '__register_diagnostic!'
+
+fn main() {
+ __diagnostic_used!(E0001);
+ //~^ ERROR macro undefined: '__diagnostic_used!'
+}
+
+__build_diagnostic_array!(DIAGNOSTICS)
+//~^ ERROR macro undefined: '__build_diagnostic_array!'
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+ let x : i16 = 22;
+ ((&x) as *const i16) as f32;
+ //~^ ERROR: cannot cast from pointer to float directly: `*const i16` as `f32`
+}
enum E {}
fn f(e: E) {
- println!("{}", (e as int).to_str()); //~ ERROR non-scalar cast
+ println!("{}", (e as int).to_string()); //~ ERROR non-scalar cast
}
fn main() {}
// error-pattern: instantiating a type parameter with an incompatible type
fn bar<T: Sized>() { }
-fn foo<type T>() { bar::<T>() }
+fn foo<Sized? T>() { bar::<T>() }
fn main() { }
// error-pattern: instantiating a type parameter with an incompatible type
fn bar<T: Sized>() { }
-fn foo<type T>() { bar::<Option<T>>() }
+fn foo<Sized? T>() { bar::<Option<T>>() }
fn main() { }
struct Foo<T> { data: T }
fn bar<T: Sized>() { }
-fn foo<type T>() { bar::<Foo<T>>() }
+fn foo<Sized? T>() { bar::<Foo<T>>() }
fn main() { }
// Unbounded.
-fn f1<type X>(x: &X) {
+fn f1<Sized? X>(x: &X) {
f2::<X>(x); //~ ERROR instantiating a type parameter with an incompatible type `X`, which does n
}
fn f2<X>(x: &X) {
}
// Bounded.
-trait T for type {}
-fn f3<type X: T>(x: &X) {
+trait T for Sized? {}
+fn f3<Sized? X: T>(x: &X) {
f4::<X>(x); //~ ERROR instantiating a type parameter with an incompatible type `X`, which does n
}
fn f4<X: T>(x: &X) {
}
// Test with unsized enum.
-enum E<type X> {
+enum E<Sized? X> {
V(X),
}
fn f5<Y>(x: &Y) {}
-fn f6<type X>(x: &X) {}
-fn f7<type X>(x1: &E<X>, x2: &E<X>) {
+fn f6<Sized? X>(x: &X) {}
+fn f7<Sized? X>(x1: &E<X>, x2: &E<X>) {
f5(x1); //~ERROR instantiating a type parameter with an incompatible type `E<X>`, which does not
f6(x2); // ok
}
// Test with unsized struct.
-struct S<type X> {
+struct S<Sized? X> {
x: X,
}
-fn f8<type X>(x1: &S<X>, x2: &S<X>) {
+fn f8<Sized? X>(x1: &S<X>, x2: &S<X>) {
f5(x1); //~ERROR instantiating a type parameter with an incompatible type `S<X>`, which does not
f6(x2); // ok
}
// Test some tuples.
-fn f9<type X>(x1: Box<S<X>>, x2: Box<E<X>>) {
+fn f9<Sized? X>(x1: Box<S<X>>, x2: Box<E<X>>) {
f5(&(*x1, 34i)); //~ERROR instantiating a type parameter with an incompatible type `(S<X>,int)`,
f5(&(32i, *x2)); //~ERROR instantiating a type parameter with an incompatible type `(int,E<X>)`,
}
// impl - bounded
trait T1<Z: T> {
}
-struct S3<type Y>;
-impl<type X: T> T1<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type
+struct S3<Sized? Y>;
+impl<Sized? X: T> T1<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type
}
// impl - unbounded
trait T2<Z> {
}
-impl<type X> T2<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type `X`
+impl<Sized? X> T2<X> for S3<X> { //ERROR instantiating a type parameter with an incompatible type `X
// impl - struct
-trait T3<type Z> {
+trait T3<Sized? Z> {
}
struct S4<Y>;
-impl<type X> T3<X> for S4<X> { //ERROR instantiating a type parameter with an incompatible type `X`
+impl<Sized? X> T3<X> for S4<X> { //ERROR instantiating a type parameter with an incompatible type `X
}
*/
// Test that bounds are sized-compatible.
trait T {}
-fn f<type Y: T>() {
+fn f<Sized? Y: T>() {
//~^ERROR incompatible bounds on type parameter Y, bound T does not allow unsized type
}
// except according to those terms.
#![feature(struct_variant)]
-// Test `type` types not allowed in fields.
+// Test `Sized?` types not allowed in fields.
-struct S1<type X> {
+struct S1<Sized? X> {
f1: X, //~ ERROR type `f1` is dynamically sized. dynamically sized types may only appear as the
f2: int,
}
-struct S2<type X> {
+struct S2<Sized? X> {
f: int,
g: X, //~ ERROR type `g` is dynamically sized. dynamically sized types may only appear as the ty
h: int,
}
-enum E<type X> {
+enum E<Sized? X> {
V1(X, int), //~ERROR type `X` is dynamically sized. dynamically sized types may only appear as t
V2{f1: X, f: int}, //~ERROR type `f1` is dynamically sized. dynamically sized types may only app
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// Test `type` local variables.
+// Test `Sized?` local variables.
-trait T for type {}
+trait T for Sized? {}
-fn f1<type X>(x: &X) {
+fn f1<Sized? X>(x: &X) {
let _: X; //~ERROR variable `_` has dynamically sized type `X`
let _: (int, (X, int)); //~ERROR variable `_` has dynamically sized type `(int,(X,int))`
let y: X; //~ERROR variable `y` has dynamically sized type `X`
let y: (int, (X, int)); //~ERROR variable `y` has dynamically sized type `(int,(X,int))`
}
-fn f2<type X: T>(x: &X) {
+fn f2<Sized? X: T>(x: &X) {
let _: X; //~ERROR variable `_` has dynamically sized type `X`
let _: (int, (X, int)); //~ERROR variable `_` has dynamically sized type `(int,(X,int))`
let y: X; //~ERROR variable `y` has dynamically sized type `X`
let y: (int, (X, int)); //~ERROR variable `y` has dynamically sized type `(int,(X,int))`
}
-fn f3<type X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
+fn f3<Sized? X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
let y: X = *x1; //~ERROR variable `y` has dynamically sized type `X`
let y = *x2; //~ERROR variable `y` has dynamically sized type `X`
let (y, z) = (*x3, 4i); //~ERROR variable `y` has dynamically sized type `X`
}
-fn f4<type X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
+fn f4<Sized? X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
let y: X = *x1; //~ERROR variable `y` has dynamically sized type `X`
let y = *x2; //~ERROR variable `y` has dynamically sized type `X`
let (y, z) = (*x3, 4i); //~ERROR variable `y` has dynamically sized type `X`
}
-fn g1<type X>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
-fn g2<type X: T>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
+fn g1<Sized? X>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
+fn g2<Sized? X: T>(x: X) {} //~ERROR variable `x` has dynamically sized type `X`
pub fn main() {
}
#[must_use]
enum MustUse { Test }
+#[must_use = "some message"]
+enum MustUseMsg { Test2 }
+
fn foo<T>() -> T { fail!() }
fn bar() -> int { return foo::<int>(); }
fn baz() -> MustUse { return foo::<MustUse>(); }
+fn qux() -> MustUseMsg { return foo::<MustUseMsg>(); }
#[allow(unused_result)]
fn test() {
foo::<int>();
foo::<MustUse>(); //~ ERROR: unused result which must be used
+ foo::<MustUseMsg>(); //~ ERROR: unused result which must be used: some message
}
#[allow(unused_result, unused_must_use)]
fn test2() {
foo::<int>();
foo::<MustUse>();
+ foo::<MustUseMsg>();
}
fn main() {
foo::<int>(); //~ ERROR: unused result
foo::<MustUse>(); //~ ERROR: unused result which must be used
+ foo::<MustUseMsg>(); //~ ERROR: unused result which must be used: some message
let _ = foo::<int>();
let _ = foo::<MustUse>();
+ let _ = foo::<MustUseMsg>();
}
}
struct List {
- list: Vec<Box<ToStr>> }
+ list: Vec<Box<ToString>> }
impl List {
- fn push(&mut self, n: Box<ToStr>) {
+ fn push(&mut self, n: Box<ToString>) {
self.list.push(n);
}
}
let n = box Number { n: 42 };
let mut l = box List { list: Vec::new() };
l.push(n);
- let x = n.to_str();
+ let x = n.to_string();
//~^ ERROR: use of moved value: `n`
}
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern:can't find crate for `std`
-
-extern crate std = "std#bogus";
C
}
-fn main() { }
\ No newline at end of file
+fn main() { }
all:
$(RUSTC) lib.rs
- ln -nsf $(call DYLIB,boot-*) $(call DYLIB,boot)
$(CC) main.c -o $(call RUN_BINFILE,main) $(call RPATH_LINK_SEARCH,$(HOST_LIB_DIR)) -lboot
$(call RUN,main)
$(call REMOVE_DYLIBS,boot)
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![crate_id="boot#0.1"]
+#![crate_name="boot"]
#![crate_type="dylib"]
extern crate rustuv;
all:
$(RUSTC) lib.rs
- ln -nsf $(call DYLIB,boot-*) $(call DYLIB,boot)
$(CC) main.c -o $(call RUN_BINFILE,main) $(call RPATH_LINK_SEARCH,$(HOST_LIB_DIR)) -lboot
$(call RUN,main)
$(call REMOVE_DYLIBS,boot)
all:
$(RUSTC) foo.rs
- ln -s $(call DYLIB,foo-*) $(call DYLIB,foo)
$(CC) bar.c -lfoo -o $(call RUN_BINFILE,bar) $(call RPATH_LINK_SEARCH,$(HOST_LIB_DIR)) -Wl,-rpath,$(TMPDIR)
$(call RUN,bar)
$(call REMOVE_DYLIBS,foo)
ifneq ($(shell uname),FreeBSD)
all:
$(RUSTC) foo.rs
- ln -s $(call STATICLIB,foo-*) $(call STATICLIB,foo)
$(CC) bar.c -lfoo -o $(call RUN_BINFILE,bar) $(EXTRAFLAGS) -lstdc++
$(call RUN,bar)
rm $(call STATICLIB,foo*)
-include ../tools.mk
all:
- [ `$(RUSTC) --crate-id crate.rs` = "foo#0.11.0" ]
- [ `$(RUSTC) --crate-name crate.rs` = "foo" ]
- [ `$(RUSTC) --crate-file-name crate.rs` = "foo" ]
- [ `$(RUSTC) --crate-file-name --crate-type=lib --test crate.rs` = "foo" ]
- [ `$(RUSTC) --crate-file-name --test lib.rs` = "mylib" ]
- $(RUSTC) --crate-file-name lib.rs
- $(RUSTC) --crate-file-name rlib.rs
+ [ `$(RUSTC) --print-crate-name crate.rs` = "foo" ]
+ [ `$(RUSTC) --print-file-name crate.rs` = "foo" ]
+ [ `$(RUSTC) --print-file-name --crate-type=lib --test crate.rs` = "foo" ]
+ [ `$(RUSTC) --print-file-name --test lib.rs` = "mylib" ]
+ $(RUSTC) --print-file-name lib.rs
+ $(RUSTC) --print-file-name rlib.rs
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![crate_id = "foo#0.11.0"]
+#![crate_name = "foo"]
// Querying about the crate metadata should *not* parse the entire crate, it
// only needs the crate attributes (which are guaranteed to be at the top) be
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![crate_id = "mylib"]
+#![crate_name = "mylib"]
#![crate_type = "lib"]
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![crate_id = "mylib"]
+#![crate_name = "mylib"]
#![crate_type = "rlib"]
--- /dev/null
+-include ../tools.mk
+
+all:
+ $(RUSTC) foo.rs
+ rm $(TMPDIR)/$(call BIN,foo)
+ $(RUSTC) foo.rs --crate-name bar
+ rm $(TMPDIR)/$(call BIN,bar)
+ $(RUSTC) foo1.rs
+ rm $(TMPDIR)/$(call BIN,foo)
+ $(RUSTC) foo1.rs --crate-name bar
+ rm $(TMPDIR)/$(call BIN,bar)
+ $(RUSTC) foo1.rs --crate-name bar -o $(TMPDIR)/bar1
+ rm $(TMPDIR)/$(call BIN,bar1)
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "foo"]
+
+fn main() {}
+
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![crate_id="foo#0.1"]
+#![crate_name = "foo"]
pub mod foo;
pub mod bar;
--- /dev/null
+-include ../tools.mk
+
+# Attempt to build this dependency tree:
+#
+# A.1 A.2
+# |\ |
+# | \ |
+# B \ C
+# \ | /
+# \|/
+# D
+#
+# Note that A.1 and A.2 are crates with the same name.
+
+all:
+ $(RUSTC) -C metadata=1 -C extra-filename=-1 a.rs
+ $(RUSTC) -C metadata=2 -C extra-filename=-2 a.rs
+ $(RUSTC) b.rs --extern a=$(TMPDIR)/liba-1.rlib
+ $(RUSTC) c.rs --extern a=$(TMPDIR)/liba-2.rlib
+ $(RUSTC) --cfg before d.rs --extern a=$(TMPDIR)/liba-1.rlib
+ $(call RUN,d)
+ $(RUSTC) --cfg after d.rs --extern a=$(TMPDIR)/liba-1.rlib
+ $(call RUN,d)
+
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "a"]
+#![crate_type = "rlib"]
+
+static FOO: uint = 3;
+
+pub fn token() -> &'static uint { &FOO }
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "b"]
+#![crate_type = "rlib"]
+
+extern crate a;
+
+static FOO: uint = 3;
+
+pub fn token() -> &'static uint { &FOO }
+pub fn a_token() -> &'static uint { a::token() }
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "c"]
+#![crate_type = "rlib"]
+
+extern crate a;
+
+static FOO: uint = 3;
+
+pub fn token() -> &'static uint { &FOO }
+pub fn a_token() -> &'static uint { a::token() }
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[cfg(before)] extern crate a;
+extern crate b;
+extern crate c;
+#[cfg(after)] extern crate a;
+
+fn t(a: &'static uint) -> uint { a as *const _ as uint }
+
+fn main() {
+ assert!(t(a::token()) == t(b::a_token()));
+ assert!(t(a::token()) != t(c::a_token()));
+}
--- /dev/null
+-include ../tools.mk
+
+all:
+ $(RUSTC) bar.rs --crate-type=rlib
+ $(RUSTC) bar.rs --crate-type=rlib -C extra-filename=-a
+ $(RUSTC) foo.rs --extern hello && exit 1 || exit 0
+ $(RUSTC) foo.rs --extern bar=no-exist && exit 1 || exit 0
+ $(RUSTC) foo.rs --extern bar=foo.rs && exit 1 || exit 0
+ $(RUSTC) foo.rs \
+ --extern bar=$(TMPDIR)/libbar.rlib \
+ --extern bar=$(TMPDIR)/libbar-a.rlib \
+ && exit 1 || exit 0
+ $(RUSTC) foo.rs \
+ --extern bar=$(TMPDIR)/libbar.rlib \
+ --extern bar=$(TMPDIR)/libbar.rlib
+ $(RUSTC) foo.rs --extern bar=$(TMPDIR)/libbar.rlib
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate bar;
+
+fn main() {}
N2[label="expr 6"];
N3[label="expr S6{val: 6,}"];
N4[label="local _x"];
- N5[label="pat S6{val: _x}"];
- N6[label="block { let S6{val: _x} = S6{val: 6,}; }"];
+ N5[label="pat S6 { val: _x }"];
+ N6[label="block { let S6 { val: _x } = S6{val: 6,}; }"];
N0 -> N2;
N2 -> N3;
N3 -> N4;
--- /dev/null
+# This test ensures that if you have the same rlib or dylib at two locations
+# in the same path that you don't hit an assertion in the compiler.
+#
+# Note that this relies on `liburl` to be in the path somewhere else,
+# and then our aux-built libraries will collide with liburl (they have
+# the same version listed)
+
+-include ../tools.mk
+
+all:
+ mkdir $(TMPDIR)/other
+ $(RUSTC) foo.rs --crate-type=dylib
+ mv $(call DYLIB,foo) $(TMPDIR)/other
+ $(RUSTC) foo.rs --crate-type=dylib
+ $(RUSTC) bar.rs -L $(TMPDIR)/other 2>&1 | \
+ grep "multiple dylib candidates"
+ rm -rf $(TMPDIR)
+ mkdir -p $(TMPDIR)/other
+ $(RUSTC) foo.rs --crate-type=rlib
+ mv $(TMPDIR)/libfoo.rlib $(TMPDIR)/other
+ $(RUSTC) foo.rs --crate-type=rlib
+ $(RUSTC) bar.rs -L $(TMPDIR)/other 2>&1 | \
+ grep "multiple rlib candidates"
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate foo;
+
+fn main() {}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "foo"]
all:
$(RUSTC) foo.rs -Z lto
- ln -s $(call STATICLIB,foo-*) $(call STATICLIB,foo)
$(CC) bar.c -lfoo -o $(call RUN_BINFILE,bar) $(EXTRACFLAGS) -lstdc++
$(call RUN,bar)
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#[crate_type = "rlib"];
+#![crate_type = "rlib"]
--- /dev/null
+-include ../tools.mk
+
+all:
+ $(RUSTC) --crate-name foo bar.rs
+ rm $(TMPDIR)/libfoo.rlib
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "rlib"]
--- /dev/null
+-include ../tools.mk
+
+all:
+ $(RUSTC) foo.rs -C metadata=a -C extra-filename=-a
+ $(RUSTC) foo.rs -C metadata=b -C extra-filename=-b
+ $(RUSTC) bar.rs \
+ --extern foo1=$(TMPDIR)/libfoo-a.rlib \
+ --extern foo2=$(TMPDIR)/libfoo-b.rlib \
+ -Z print-link-args
+ $(call RUN,bar)
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate foo1;
+extern crate foo2;
+
+fn main() {
+ let a = foo1::foo();
+ let b = foo2::foo();
+ assert!(a as *const _ != b as *const _);
+}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "foo"]
+#![crate_type = "rlib"]
+
+static FOO: uint = 3;
+
+pub fn foo() -> &'static uint { &FOO }
--- /dev/null
+-include ../tools.mk
+
+all:
+ $(RUSTC) foo.rs -C metadata=a -C extra-filename=-1 --crate-type=rlib
+ $(RUSTC) foo.rs -C metadata=b -C extra-filename=-2 --crate-type=rlib
+ $(RUSTC) bar.rs \
+ --extern foo1=$(TMPDIR)/libfoo-1.rlib \
+ --extern foo2=$(TMPDIR)/libfoo-2.rlib \
+ 2>&1 | grep "using multiple versions of crate .foo."
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate foo1;
+extern crate foo2;
+
+fn main() {}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn foo() {}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![crate_id = "bar"]
+#![crate_name = "bar"]
fn main() {}
/// *wow*
pub trait Doge { }
+
+ pub struct Foo { x: int, y: uint }
+
+ pub fn prawns((a, b): (int, uint), Foo { x, y }: Foo) { }
}
-include ../tools.mk
all:
- $(RUSTC) foo.rs -o $(TMPDIR)/.foo
- rm $(TMPDIR)/.foo
- $(RUSTC) foo.rs -o $(TMPDIR)/.foo.bar
- rm $(TMPDIR)/.foo.bar
- $(RUSTC) foo.rs -o $(TMPDIR)/+foo+bar
- rm $(TMPDIR)/$(call BIN,+foo+bar)
+ cp foo.rs $(TMPDIR)/.foo.rs
+ $(RUSTC) $(TMPDIR)/.foo.rs 2>&1 \
+ | grep "invalid character.*in crate name:"
+ cp foo.rs $(TMPDIR)/.foo.bar
+ $(RUSTC) $(TMPDIR)/.foo.bar 2>&1 \
+ | grep "invalid character.*in crate name:"
+ cp foo.rs $(TMPDIR)/+foo+bar
+ $(RUSTC) $(TMPDIR)/+foo+bar 2>&1 \
+ | grep "invalid character.*in crate name:"
impl<'a,A> iterable<A> for &'a [A] {
fn iterate(&self, f: |x: &A| -> bool) -> bool {
- self.iter().advance(f)
+ self.iter().all(f)
}
}
impl<A> iterable<A> for Vec<A> {
fn iterate(&self, f: |x: &A| -> bool) -> bool {
- self.iter().advance(f)
+ self.iter().all(f)
}
}
}
fn runtest(me: &str) {
- let mut env = os::env().move_iter()
- .map(|(ref k, ref v)| {
- (k.to_string(), v.to_string())
- }).collect::<Vec<(String,String)>>();
- match env.iter()
- .position(|&(ref s, _)| "RUST_BACKTRACE" == s.as_slice()) {
- Some(i) => { env.remove(i); }
- None => {}
- }
- env.push(("RUST_BACKTRACE".to_string(), "1".to_string()));
-
// Make sure that the stack trace is printed
- let mut p = Command::new(me).arg("fail").env(env.as_slice()).spawn().unwrap();
+ let mut p = Command::new(me).arg("fail").env("RUST_BACKTRACE", "1").spawn().unwrap();
let out = p.wait_with_output().unwrap();
assert!(!out.status.success());
let s = str::from_utf8(out.error.as_slice()).unwrap();
"bad output3: {}", s);
// Make sure a stack trace isn't printed too many times
- let mut p = Command::new(me).arg("double-fail").env(env.as_slice()).spawn().unwrap();
+ let mut p = Command::new(me).arg("double-fail")
+ .env("RUST_BACKTRACE", "1").spawn().unwrap();
let out = p.wait_with_output().unwrap();
assert!(!out.status.success());
let s = str::from_utf8(out.error.as_slice()).unwrap();
use std::collections::Bitv;
fn bitv_test() {
- let mut v1 = box Bitv::new(31, false);
- let v2 = box Bitv::new(31, true);
+ let mut v1 = box Bitv::with_capacity(31, false);
+ let v2 = box Bitv::with_capacity(31, true);
v1.union(v2);
}
assert_eq!(!true, false);
assert_eq!(!false, true);
- let s = false.to_str();
+ let s = false.to_string();
assert_eq!(s.as_slice(), "false");
- let s = true.to_str();
+ let s = true.to_string();
assert_eq!(s.as_slice(), "true");
assert!(true > false);
fn iter_ints(x: &Ints, f: |x: &int| -> bool) -> bool {
let l = x.values.len();
- range(0u, l).advance(|i| f(x.values.get(i)))
+ range(0u, l).all(|i| f(x.values.get(i)))
}
pub fn main() {
_ => fail!(),
}
+ let buf = vec!(97u8, 98, 99, 100);
+ assert_eq!(match buf.slice(0, 3) {
+ b"def" => 1u,
+ b"abc" => 2u,
+ _ => 3u
+ }, 2);
+
assert_eq!(BAZ, &[97u8, 92u8, 110u8]);
assert_eq!(br"a\n", &[97u8, 92u8, 110u8]);
assert_eq!(br"a\n", b"a\\n");
debug!("debug");
info!("info");
});
- let s = r.read_to_str().unwrap();
+ let s = r.read_to_string().unwrap();
assert!(s.as_slice().contains("info"));
assert!(!s.as_slice().contains("debug"));
}
// aux-build:cci_class_cast.rs
extern crate cci_class_cast;
-use std::to_str::ToStr;
+use std::to_str::ToString;
use cci_class_cast::kitty::cat;
-fn print_out(thing: Box<ToStr>, expected: String) {
- let actual = thing.to_str();
+fn print_out(thing: Box<ToString>, expected: String) {
+ let actual = thing.to_string();
println!("{}", actual);
assert_eq!(actual.to_string(), expected);
}
pub fn main() {
- let nyan: Box<ToStr> = box cat(0u, 2, "nyan".to_string()) as Box<ToStr>;
+ let nyan: Box<ToString> = box cat(0u, 2, "nyan".to_string()) as Box<ToString>;
print_out(nyan, "nyan".to_string());
}
}
}
-fn print_out(thing: Box<ToStr>, expected: String) {
- let actual = thing.to_str();
+fn print_out(thing: Box<ToString>, expected: String) {
+ let actual = thing.to_string();
println!("{}", actual);
assert_eq!(actual.to_string(), expected);
}
pub fn main() {
- let nyan: Box<ToStr> = box cat(0u, 2, "nyan".to_string()) as Box<ToStr>;
+ let nyan: Box<ToString> = box cat(0u, 2, "nyan".to_string()) as Box<ToString>;
print_out(nyan, "nyan".to_string());
}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags:--crate-name crate-name-attr-used -F unused-attribute
+
+#![crate_name = "test"]
+
+fn main() {}
+++ /dev/null
-// Copyright 2012-2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve1-1.rs
-// aux-build:crateresolve1-2.rs
-// aux-build:crateresolve1-3.rs
-
-extern crate crateresolve1 = "crateresolve1#0.2";
-
-pub fn main() {
- assert_eq!(crateresolve1::f(), 20);
-}
+++ /dev/null
-// Copyright 2012-2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve2-1.rs
-// aux-build:crateresolve2-2.rs
-// aux-build:crateresolve2-3.rs
-
-mod a {
- extern crate crateresolve2 = "crateresolve2#0.1";
- pub fn f() { assert!(crateresolve2::f() == 10); }
-}
-
-mod b {
- extern crate crateresolve2 = "crateresolve2#0.2";
- pub fn f() { assert!(crateresolve2::f() == 20); }
-}
-
-mod c {
- extern crate crateresolve2 = "crateresolve2#0.3";
- pub fn f() { assert!(crateresolve2::f() == 30); }
-}
-
-pub fn main() {
- a::f();
- b::f();
- c::f();
-}
+++ /dev/null
-// Copyright 2012-2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve3-1.rs
-// aux-build:crateresolve3-2.rs
-
-// verify able to link with crates with same name but different versions
-// as long as no name collision on invoked functions.
-
-mod a {
- extern crate crateresolve3 = "crateresolve3#0.1";
- pub fn f() { assert!(crateresolve3::f() == 10); }
-}
-
-mod b {
- extern crate crateresolve3 = "crateresolve3#0.2";
- pub fn f() { assert!(crateresolve3::g() == 20); }
-}
-
-pub fn main() {
- a::f();
- b::f();
-}
+++ /dev/null
-// Copyright 2012-2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve4a-1.rs
-// aux-build:crateresolve4a-2.rs
-// aux-build:crateresolve4b-1.rs
-// aux-build:crateresolve4b-2.rs
-
-pub mod a {
- extern crate crateresolve4b = "crateresolve4b#0.1";
- pub fn f() { assert!(crateresolve4b::f() == 20); }
-}
-
-pub mod b {
- extern crate crateresolve4b = "crateresolve4b#0.2";
- pub fn f() { assert!(crateresolve4b::g() == 10); }
-}
-
-pub fn main() {
- a::f();
- b::f();
-}
+++ /dev/null
-// Copyright 2012-2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve5-1.rs
-// aux-build:crateresolve5-2.rs
-
-extern crate cr5_1 = "crateresolve5#0.1";
-extern crate cr5_2 = "crateresolve5#0.2";
-
-pub fn main() {
- // Structural types can be used between two versions of the same crate
- assert!(cr5_1::struct_nameval().name == cr5_2::struct_nameval().name);
- assert!(cr5_1::struct_nameval().val == cr5_2::struct_nameval().val);
- // Make sure these are actually two different crates
- assert!(cr5_1::f() == 10 && cr5_2::f() == 20);
-}
+++ /dev/null
-// Copyright 2012-2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:crateresolve8-1.rs
-
-#![crate_id="crateresolve8#0.1"]
-
-extern crate crateresolve8 = "crateresolve8#0.1";
-//extern crate crateresolve8(vers = "0.1");
-
-pub fn main() {
- assert_eq!(crateresolve8::f(), 20);
-}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This briefuly tests the capability of `Cell` and `RefCell` to implement the
+// `Encodable` and `Decodable` traits via `#[deriving(Encodable, Decodable)]`
+
+extern crate serialize;
+
+use std::cell::{Cell, RefCell};
+use std::io::MemWriter;
+use serialize::{Encodable, Decodable};
+use serialize::ebml;
+use serialize::ebml::writer::Encoder;
+use serialize::ebml::reader::Decoder;
+
+#[deriving(Encodable, Decodable)]
+struct A {
+ baz: int
+}
+
+#[deriving(Encodable, Decodable)]
+struct B {
+ foo: Cell<bool>,
+ bar: RefCell<A>,
+}
+
+fn main() {
+ let obj = B {
+ foo: Cell::new(true),
+ bar: RefCell::new( A { baz: 2 } )
+ };
+ let mut w = MemWriter::new();
+ {
+ let mut e = Encoder::new(&mut w);
+ match obj.encode(&mut e) {
+ Ok(()) => (),
+ Err(e) => fail!("Failed to encode: {}", e)
+ };
+ }
+ let doc = ebml::Doc::new(w.get_ref());
+ let mut dec = Decoder::new(doc);
+ let obj2: B = match Decodable::decode(&mut dec) {
+ Ok(v) => v,
+ Err(e) => fail!("Failed to decode: {}", e)
+ };
+ assert!(obj.foo.get() == obj2.foo.get());
+ assert!(obj.bar.borrow().baz == obj2.bar.borrow().baz);
+}
}
pub fn main() {
- assert_eq!(B1.to_str(), "B1".to_string());
- assert_eq!(B2.to_str(), "B2".to_string());
- assert_eq!(C1(3).to_str(), "C1(3)".to_string());
- assert_eq!(C2(B2).to_str(), "C2(B2)".to_string());
- assert_eq!(D1{ a: 2 }.to_str(), "D1 { a: 2 }".to_string());
- assert_eq!(E.to_str(), "E".to_string());
- assert_eq!(F(3).to_str(), "F(3)".to_string());
- assert_eq!(G(3, 4).to_str(), "G(3, 4)".to_string());
- assert_eq!(G(3, 4).to_str(), "G(3, 4)".to_string());
- assert_eq!(I{ a: 2, b: 4 }.to_str(), "I { a: 2, b: 4 }".to_string());
- assert_eq!(J(Custom).to_str(), "J(yay)".to_string());
+ assert_eq!(B1.to_string(), "B1".to_string());
+ assert_eq!(B2.to_string(), "B2".to_string());
+ assert_eq!(C1(3).to_string(), "C1(3)".to_string());
+ assert_eq!(C2(B2).to_string(), "C2(B2)".to_string());
+ assert_eq!(D1{ a: 2 }.to_string(), "D1 { a: 2 }".to_string());
+ assert_eq!(E.to_string(), "E".to_string());
+ assert_eq!(F(3).to_string(), "F(3)".to_string());
+ assert_eq!(G(3, 4).to_string(), "G(3, 4)".to_string());
+ assert_eq!(G(3, 4).to_string(), "G(3, 4)".to_string());
+ assert_eq!(I{ a: 2, b: 4 }.to_string(), "I { a: 2, b: 4 }".to_string());
+ assert_eq!(J(Custom).to_string(), "J(yay)".to_string());
}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+use std::gc::Gc;
+use std::mem::size_of;
+
+trait Trait {}
+
+fn main() {
+ // Closures - || / proc()
+ assert_eq!(size_of::<proc()>(), size_of::<Option<proc()>>());
+ assert_eq!(size_of::<||>(), size_of::<Option<||>>());
+
+ // Functions
+ assert_eq!(size_of::<fn(int)>(), size_of::<Option<fn(int)>>());
+ assert_eq!(size_of::<extern "C" fn(int)>(), size_of::<Option<extern "C" fn(int)>>());
+
+ // Slices - &str / &[T] / &mut [T]
+ assert_eq!(size_of::<&str>(), size_of::<Option<&str>>());
+ assert_eq!(size_of::<&[int]>(), size_of::<Option<&[int]>>());
+ assert_eq!(size_of::<&mut [int]>(), size_of::<Option<&mut [int]>>());
+
+ // Traits - Box<Trait> / &Trait / &mut Trait
+ assert_eq!(size_of::<Box<Trait>>(), size_of::<Option<Box<Trait>>>());
+ assert_eq!(size_of::<&Trait>(), size_of::<Option<&Trait>>());
+ assert_eq!(size_of::<&mut Trait>(), size_of::<Option<&mut Trait>>());
+
+ // Pointers - Box<T> / Gc<T>
+ assert_eq!(size_of::<Box<int>>(), size_of::<Option<Box<int>>>());
+ assert_eq!(size_of::<Gc<int>>(), size_of::<Option<Gc<int>>>());
+
+}
#![feature(macro_rules)]
use s = std::num::strconv;
-use to_str = std::num::strconv::float_to_str_common;
+use to_string = std::num::strconv::float_to_str_common;
macro_rules! t(($a:expr, $b:expr) => { { let (r, _) = $a; assert_eq!(r, $b.to_string()) } })
pub fn main() {
// Basic usage
- t!(to_str(1.2345678e-5f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpDec, false),
+ t!(to_string(1.2345678e-5f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpDec, false),
"1.234568e-5")
// Hexadecimal output
- t!(to_str(7.281738281250e+01f64, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false),
+ t!(to_string(7.281738281250e+01f64, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false),
"+1.2345p+6")
- t!(to_str(-1.777768135071e-02f64, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false),
+ t!(to_string(-1.777768135071e-02f64, 16u, true, s::SignAll, s::DigMax(6), s::ExpBin, false),
"-1.2345p-6")
// Some denormals
- t!(to_str(4.9406564584124654e-324f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false),
+ t!(to_string(4.9406564584124654e-324f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false),
"1p-1074")
- t!(to_str(2.2250738585072009e-308f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false),
+ t!(to_string(2.2250738585072009e-308f64, 10u, true, s::SignNeg, s::DigMax(6), s::ExpBin, false),
"1p-1022")
}
//aux-build:extern-crosscrate-source.rs
-extern crate externcallback = "externcallback#0.1";
+extern crate externcallback;
fn fact(n: uint) -> uint {
unsafe {
pub fn main() {
let arr = [1,2,3];
let struc = Struc {a: 13u8, b: arr, c: 42};
- let s = repr::repr_to_str(&struc);
+ let s = repr::repr_to_string(&struc);
assert_eq!(s, "Struc{a: 13u8, b: [1, 2, 3], c: 42}".to_string());
}
fn main() {
// Generate sieve of Eratosthenes for n up to 1e6
let n = 1000000u;
- let sieve = Bitv::new(n+1, true);
+ let mut sieve = Bitv::with_capacity(n+1, true);
let limit: uint = (n as f32).sqrt() as uint;
for i in range(2, limit+1) {
if sieve[i] {
let mut j = 0;
while i*i + j*i <= n {
- sieve[i*i+j*i] = false;
+ sieve.set(i*i+j*i, false);
j += 1;
}
}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(phase)]
+extern crate native;
+#[phase(plugin)]
+extern crate green;
+
+use native::NativeTaskBuilder;
+use std::io::{TempDir, Command, fs};
+use std::os;
+use std::task::TaskBuilder;
+
+// FIXME(#15149) libgreen still needs to be update. There is an open PR for it
+// but it is not yet merged.
+// green_start!(main)
+
+fn main() {
+ // If we're the child, make sure we were invoked correctly
+ let args = os::args();
+ if args.len() > 1 && args.get(1).as_slice() == "child" {
+ return assert_eq!(args.get(0).as_slice(), "mytest");
+ }
+
+ test();
+ let (tx, rx) = channel();
+ TaskBuilder::new().native().spawn(proc() {
+ tx.send(test());
+ });
+ rx.recv();
+}
+
+fn test() {
+ // If we're the parent, copy our own binary to a tempr directory, and then
+ // make it executable.
+ let dir = TempDir::new("mytest").unwrap();
+ let me = os::self_exe_name().unwrap();
+ let dest = dir.path().join(format!("mytest{}", os::consts::EXE_SUFFIX));
+ fs::copy(&me, &dest).unwrap();
+
+ // Append the temp directory to our own PATH.
+ let mut path = os::split_paths(os::getenv("PATH").unwrap_or(String::new()));
+ path.push(dir.path().clone());
+ let path = os::join_paths(path.as_slice()).unwrap();
+
+ Command::new("mytest").env("PATH", path.as_slice())
+ .arg("child")
+ .spawn().unwrap();
+}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-win32
+
+#![feature(link_args)]
+
+#[link_args="-lc -lm"]
+#[link_args=" -lc"]
+#[link_args="-lc "]
+extern {}
+
+fn main() {}
mod test {
#[test]
- pub fn trivial_to_str() {
- assert!(lambda.to_str() == "\\")
+ pub fn trivial_to_string() {
+ assert!(lambda.to_string() == "\\")
}
}
enum what { }
-fn what_to_str(x: what) -> String
+fn what_to_string(x: what) -> String
{
match x {
}
let mut table = HashMap::new();
table.insert("one".to_string(), 1i);
table.insert("two".to_string(), 2i);
- assert!(check_strs(table.to_str().as_slice(), "{one: 1, two: 2}") ||
- check_strs(table.to_str().as_slice(), "{two: 2, one: 1}"));
+ assert!(check_strs(table.to_string().as_slice(), "{one: 1, two: 2}") ||
+ check_strs(table.to_string().as_slice(), "{two: 2, one: 1}"));
}
}
}
-// Allows AsciiArt to be converted to a string using the libcore ToStr trait.
+// Allows AsciiArt to be converted to a string using the libcore ToString trait.
// Note that the %s fmt! specifier will not call this automatically.
impl fmt::Show for AsciiArt {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fn test_ascii_art_ctor() {
let art = AsciiArt(3, 3, '*');
- assert!(check_strs(art.to_str().as_slice(), "...\n...\n..."));
+ assert!(check_strs(art.to_string().as_slice(), "...\n...\n..."));
}
art.add_pt(0, 0);
art.add_pt(0, -10);
art.add_pt(1, 2);
- assert!(check_strs(art.to_str().as_slice(), "*..\n...\n.*."));
+ assert!(check_strs(art.to_string().as_slice(), "*..\n...\n.*."));
}
let mut art = AsciiArt(4, 4, '*');
art.add_rect(Rect {top_left: Point {x: 0, y: 0}, size: Size {width: 4, height: 4}});
art.add_point(Point {x: 2, y: 2});
- assert!(check_strs(art.to_str().as_slice(), "****\n*..*\n*.**\n****"));
+ assert!(check_strs(art.to_string().as_slice(), "****\n*..*\n*.**\n****"));
}
pub fn main() {
pub fn main() {
trait Text {
- fn to_str(&self) -> String;
+ fn to_string(&self) -> String;
}
fn to_string(t: Box<Text>) {
- println!("{}", t.to_str());
+ println!("{}", t.to_string());
}
}
}
}
-priv fn cmd_to_str(cmd: ~[String]) -> String {
+priv fn cmd_to_string(cmd: ~[String]) -> String {
let mut res = "*".to_string();
- res.push_str(cmd.len().to_str());
+ res.push_str(cmd.len().to_string());
res.push_str("\r\n");
for s in cmd.iter() {
- res.push_str(["$".to_string(), s.len().to_str(), "\r\n".to_string(),
+ res.push_str(["$".to_string(), s.len().to_string(), "\r\n".to_string(),
(*s).clone(), "\r\n".to_string()].concat() );
}
res
}
fn query(cmd: ~[String], sb: TcpSocketBuf) -> Result {
- let cmd = cmd_to_str(cmd);
+ let cmd = cmd_to_string(cmd);
//println!("{}", cmd);
sb.write_str(cmd);
let res = parse_response(@sb as @io::Reader);
}
fn query2(cmd: ~[String]) -> Result {
- let _cmd = cmd_to_str(cmd);
+ let _cmd = cmd_to_string(cmd);
io::with_str_reader("$3\r\nXXX\r\n".to_string())(|sb| {
let res = parse_response(@sb as @io::Reader);
println!("{:?}", res);
type FontTableTag = u32;
trait FontTableTagConversions {
- fn tag_to_str(self);
+ fn tag_to_string(self);
}
impl FontTableTagConversions for FontTableTag {
- fn tag_to_str(self) {
+ fn tag_to_string(self) {
&self;
}
}
pub fn main() {
- 5.tag_to_str();
+ 5.tag_to_string();
}
// except according to those terms.
struct T (&'static [int]);
-static t : T = T (&'static [5, 4, 3]);
+static t : T = T (&[5, 4, 3]);
pub fn main () {
let T(ref v) = t;
assert_eq!(v[0], 5);
fn get_mut<'r>(&'r mut self) -> &'r mut FooBar;
}
-macro_rules! generate_test(($type_:path, $field:expr) => (
+macro_rules! generate_test(($type_:path, $slf:ident, $field:expr) => (
impl Test for $type_ {
- fn get_immut<'r>(&'r self) -> &'r FooBar {
+ fn get_immut<'r>(&'r $slf) -> &'r FooBar {
&$field as &FooBar
}
- fn get_mut<'r>(&'r mut self) -> &'r mut FooBar {
+ fn get_mut<'r>(&'r mut $slf) -> &'r mut FooBar {
&mut $field as &mut FooBar
}
}
))
-generate_test!(Foo, self.bar)
+generate_test!(Foo, self, self.bar)
pub fn main() {
let mut foo: Foo = Foo { bar: Bar(42) };
static instance: UninterpretedOption_NamePart = UninterpretedOption_NamePart {
name_part: None,
};
- &'static instance
+ &instance
}
}
+++ /dev/null
-// Copyright 2012-2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// aux-build:issue2378a.rs
-// aux-build:issue2378b.rs
-
-extern crate issue2378a;
-extern crate issue2378b;
-
-use issue2378a::{just};
-use issue2378b::{two_maybes};
-
-pub fn main() {
- let x = two_maybes{a: just(3i), b: just(5i)};
- assert_eq!(x[0u], (3, 5));
-}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(macro_rules)]
+
+struct A;
+
+macro_rules! make_thirteen_method {() => (pub fn thirteen(&self)->int {13})}
+impl A { make_thirteen_method!() }
+
+fn main() {
+ assert_eq!(A.thirteen(),13);
+}
+
+
+
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+ let value = Some(1i);
+ assert_eq!(match value {
+ ref a @ Some(_) => a,
+ ref b @ None => b
+ }, &Some(1i));
+ assert_eq!(match value {
+ ref a @ ref _c @ Some(_) => a,
+ ref b @ None => b
+ }, &Some(1i));
+ assert_eq!(match value {
+ _a @ ref c @ Some(_) => c,
+ ref b @ None => b
+ }, &Some(1i));
+ assert_eq!(match "foobarbaz" {
+ _a @ b @ _ => b
+ }, "foobarbaz");
+
+ let a @ b @ c = "foobarbaz";
+ assert_eq!(a, "foobarbaz");
+ assert_eq!(b, "foobarbaz");
+ assert_eq!(c, "foobarbaz");
+ let value = Some(true);
+ let ref a @ b @ ref c = value;
+ assert_eq!(a, &Some(true));
+ assert_eq!(b, Some(true));
+ assert_eq!(c, &Some(true));
+}
}
fn transform(x: Option<int>) -> Option<String> {
- x.bind(|n| Some(*n + 1) ).bind(|n| Some(n.to_str()) )
+ x.bind(|n| Some(*n + 1) ).bind(|n| Some(n.to_string()) )
}
pub fn main() {
}
}
-fn to_str(sb: StringBuffer) -> String {
+fn to_string(sb: StringBuffer) -> String {
sb.s
}
};
sb.append("Hello, ");
sb.append("World!");
- let str = to_str(sb);
+ let str = to_string(sb);
assert_eq!(str.as_slice(), "Hello, World!");
}
// Tests that the new `box` syntax works with unique pointers and GC pointers.
use std::gc::{Gc, GC};
-use std::owned::{Box, HEAP};
+use std::boxed::{Box, HEAP};
struct Structure {
x: int,
let c = box()(3i + 4);
let d = box(GC)(5i + 6);
}
-
}
pub fn main() {
- println!("{}", Thingy { x: 1, y: 2 }.to_str());
- println!("{}", PolymorphicThingy { x: Thingy { x: 1, y: 2 } }.to_str());
+ println!("{}", Thingy { x: 1, y: 2 }.to_string());
+ println!("{}", PolymorphicThingy { x: Thingy { x: 1, y: 2 } }.to_string());
}
}
impl ops::Index<bool,int> for Point {
- fn index(&self, x: &bool) -> int {
- if *x { self.x } else { self.y }
+ fn index<'a>(&'a self, x: &bool) -> &'a int {
+ if *x {
+ &self.x
+ } else {
+ &self.y
+ }
}
}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+// Test to make sure the destructors run in the right order.
+// Each destructor sets it's tag in the corresponding entry
+// in ORDER matching up to when it ran.
+// Correct order is: matched, inner, outer
+
+static mut ORDER: [uint, ..3] = [0, 0, 0];
+static mut INDEX: uint = 0;
+
+struct A;
+impl Drop for A {
+ fn drop(&mut self) {
+ unsafe {
+ ORDER[INDEX] = 1;
+ INDEX = INDEX + 1;
+ }
+ }
+}
+
+struct B;
+impl Drop for B {
+ fn drop(&mut self) {
+ unsafe {
+ ORDER[INDEX] = 2;
+ INDEX = INDEX + 1;
+ }
+ }
+}
+
+struct C;
+impl Drop for C {
+ fn drop(&mut self) {
+ unsafe {
+ ORDER[INDEX] = 3;
+ INDEX = INDEX + 1;
+ }
+ }
+}
+
+fn main() {
+ {
+ let matched = A;
+ let _outer = C;
+ {
+ match matched {
+ _s => {}
+ }
+ let _inner = B;
+ }
+ }
+ unsafe {
+ assert_eq!(&[1, 2, 3], ORDER.as_slice());
+ }
+}
}
impl<K:PartialEq,V:Clone> Index<K,V> for AssociationList<K,V> {
- fn index(&self, index: &K) -> V {
+ fn index<'a>(&'a self, index: &K) -> &'a V {
for pair in self.pairs.iter() {
if pair.key == *index {
- return pair.value.clone();
+ return &pair.value
}
}
fail!("No value found for key: {:?}", index);
// N.B. This is required because method lookup hasn't been performed so
// we don't know whether the called method takes mutable self, before
// the dereference itself is type-checked (a chicken-and-egg problem).
- (*n).to_str();
+ (*n).to_string();
assert_eq!(n.counts(), (2, 4));
// Mutable deref used for calling a method taking &mut self.
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Foo {
+ x: int,
+ y: int,
+}
+
+impl Index<int,int> for Foo {
+ fn index<'a>(&'a self, z: &int) -> &'a int {
+ if *z == 0 {
+ &self.x
+ } else {
+ &self.y
+ }
+ }
+}
+
+impl IndexMut<int,int> for Foo {
+ fn index_mut<'a>(&'a mut self, z: &int) -> &'a mut int {
+ if *z == 0 {
+ &mut self.x
+ } else {
+ &mut self.y
+ }
+ }
+}
+
+fn main() {
+ let mut f = Foo {
+ x: 1,
+ y: 2,
+ };
+ assert_eq!(f[1], 2);
+ f[0] = 3;
+ assert_eq!(f[0], 3);
+ {
+ let p = &mut f[1];
+ *p = 4;
+ }
+ {
+ let p = &f[1];
+ assert_eq!(*p, 4);
+ }
+}
+
let p = Command::new(&child_path)
.arg(arg)
.cwd(&cwd)
- .env(my_env.append_one(env).as_slice())
+ .env_set_all(my_env.append_one(env).as_slice())
.spawn().unwrap().wait_with_output().unwrap();
// display the output
use std::collections::{ Map, MutableMap};
use std::str::{SendStr, Owned, Slice};
-use std::to_str::ToStr;
+use std::to_str::ToString;
use self::collections::TreeMap;
use std::option::Some;
impl uint_utils for uint {
fn str(&self) -> String {
- self.to_str()
+ self.to_string()
}
fn multi(&self, f: |uint|) {
let mut c = 0u;
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+ let x = "\\\\\
+ ";
+ assert!(x == r"\\"); // extraneous whitespace stripped
+}
--- /dev/null
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:xcrate_struct_aliases.rs
+extern crate xcrate_struct_aliases;
+
+use xcrate_struct_aliases::{S, S2};
+
+fn main() {
+ let s = S2 {
+ x: 1,
+ y: 2,
+ };
+ match s {
+ S2 {
+ x: x,
+ y: y
+ } => {
+ assert_eq!(x, 1);
+ assert_eq!(y, 2);
+ }
+ }
+}
+
--- /dev/null
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct S {
+ x: int,
+ y: int,
+}
+
+type S2 = S;
+
+fn main() {
+ let s = S2 {
+ x: 1,
+ y: 2,
+ };
+ match s {
+ S2 {
+ x: x,
+ y: y
+ } => {
+ assert_eq!(x, 1);
+ assert_eq!(y, 2);
+ }
+ }
+}
+
});
assert!(res.is_err());
- let output = reader.read_to_str().unwrap();
+ let output = reader.read_to_string().unwrap();
assert!(output.as_slice().contains("Hello, world!"));
}
iotest!(fn eventual_timeout() {
use native;
let addr = next_test_ip4();
- let host = addr.ip.to_str();
+ let host = addr.ip.to_string();
let port = addr.port;
// Use a native task to receive connections because it turns out libuv is
iotest!(fn timeout_success() {
let addr = next_test_ip4();
- let host = addr.ip.to_str();
+ let host = addr.ip.to_string();
let port = addr.port;
let _l = TcpListener::bind(host.as_slice(), port).unwrap().listen();
for _ in range(0u, 1000) {
let tx = tx.clone();
TaskBuilder::new().stack_size(64 * 1024).spawn(proc() {
- let host = addr.ip.to_str();
+ let host = addr.ip.to_string();
let port = addr.port;
match TcpStream::connect(host.as_slice(), port) {
Ok(stream) => {
let tests = __test::TESTS;
assert!(
- tests.iter().any(|t| t.desc.name.to_str().as_slice() == "shouldignore" &&
+ tests.iter().any(|t| t.desc.name.to_string().as_slice() == "shouldignore" &&
t.desc.ignore));
assert!(
- tests.iter().any(|t| t.desc.name.to_str().as_slice() == "shouldnotignore" &&
+ tests.iter().any(|t| t.desc.name.to_string().as_slice() == "shouldnotignore" &&
!t.desc.ignore));
}
impl to_str for int {
fn to_str_(&self) -> String {
- self.to_str()
+ self.to_string()
}
}
trait to_str {
- fn to_string(&self) -> String;
+ fn to_string_(&self) -> String;
}
impl to_str for int {
- fn to_string(&self) -> String { self.to_str() }
+ fn to_string_(&self) -> String { self.to_string() }
}
impl to_str for String {
- fn to_string(&self) -> String { self.clone() }
+ fn to_string_(&self) -> String { self.clone() }
}
impl to_str for () {
- fn to_string(&self) -> String { "()".to_string() }
+ fn to_string_(&self) -> String { "()".to_string() }
}
trait map<T> {
x.map(|_e| "hi".to_string() )
}
fn bar<U:to_str,T:map<U>>(x: T) -> Vec<String> {
- x.map(|_e| _e.to_string() )
+ x.map(|_e| _e.to_string_() )
}
pub fn main() {
trait to_str {
- fn to_string(&self) -> String;
+ fn to_string_(&self) -> String;
}
impl to_str for int {
- fn to_string(&self) -> String { self.to_str() }
+ fn to_string_(&self) -> String { self.to_string() }
}
impl<T:to_str> to_str for Vec<T> {
- fn to_string(&self) -> String {
+ fn to_string_(&self) -> String {
format!("[{}]",
self.iter()
- .map(|e| e.to_string())
+ .map(|e| e.to_string_())
.collect::<Vec<String>>()
.connect(", "))
}
}
pub fn main() {
- assert!(1.to_string() == "1".to_string());
- assert!((vec!(2i, 3, 4)).to_string() == "[2, 3, 4]".to_string());
+ assert!(1.to_string_() == "1".to_string());
+ assert!((vec!(2i, 3, 4)).to_string_() == "[2, 3, 4]".to_string());
fn indirect<T:to_str>(x: T) -> String {
- format!("{}!", x.to_string())
+ format!("{}!", x.to_string_())
}
assert!(indirect(vec!(10i, 20)) == "[10, 20]!".to_string());
// size of struct may be not equal to size of struct, and
// compiler crashes in internal assertion check.
};
- &'static instance
+ &instance
}
fn non_default_instance() -> &'static Request {
foo: TestSome(0x1020304050607080),
bar: 19,
};
- &'static instance
+ &instance
}
pub fn main() {
// This test checks that the `_` type placeholder works
// correctly for enabling type inference.
-static CONSTEXPR: *const int = &'static 413 as *const _;
+static CONSTEXPR: *const int = &413 as *const _;
pub fn main() {
let x: Vec<_> = range(0u, 5).collect();
// Make sure the destructor is run for unit-like structs.
-use std::owned::AnyOwnExt;
+use std::boxed::BoxAny;
use std::task;
struct Foo;
let _b = Foo;
});
- let s = x.unwrap_err().move::<&'static str>().unwrap();
+ let s = x.unwrap_err().downcast::<&'static str>().unwrap();
assert_eq!(s.as_slice(), "This failure should happen.");
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// Test syntax checks for `type` keyword.
+// Test syntax checks for `Sized?` syntax.
-trait T1 for type {}
-pub trait T2 for type {}
-trait T3<X: T1> for type: T2 {}
-trait T4<type X> {}
-trait T5<type X, Y> {}
-trait T6<Y, type X> {}
-trait T7<type X, type Y> {}
-trait T8<type X: T2> {}
-struct S1<type X>;
-enum E<type X> {}
-impl <type X> T1 for S1<X> {}
-fn f<type X>() {}
+trait T1 for Sized? {}
+pub trait T2 for Sized? {}
+trait T3<X: T1> for Sized?: T2 {}
+trait T4<Sized? X> {}
+trait T5<Sized? X, Y> {}
+trait T6<Y, Sized? X> {}
+trait T7<Sized? X, Sized? Y> {}
+trait T8<Sized? X: T2> {}
+struct S1<Sized? X>;
+enum E<Sized? X> {}
+impl <Sized? X> T1 for S1<X> {}
+fn f<Sized? X>() {}
pub fn main() {
}
// Test sized-ness checking in substitution.
// Unbounded.
-fn f1<type X>(x: &X) {
+fn f1<Sized? X>(x: &X) {
f1::<X>(x);
}
fn f2<X>(x: &X) {
}
// Bounded.
-trait T for type {}
-fn f3<type X: T>(x: &X) {
+trait T for Sized? {}
+fn f3<Sized? X: T>(x: &X) {
f3::<X>(x);
}
fn f4<X: T>(x: &X) {
}
// Self type.
-trait T2 for type {
+trait T2 for Sized? {
fn f() -> Box<Self>;
}
struct S;
box S
}
}
-fn f5<type X: T2>(x: &X) {
+fn f5<Sized? X: T2>(x: &X) {
let _: Box<X> = T2::f();
}
fn f6<X: T2>(x: &X) {
let _: Box<X> = T2::f();
}
-trait T3 for type {
+trait T3 for Sized? {
fn f() -> Box<Self>;
}
impl T3 for S {
box S
}
}
-fn f7<type X: T3>(x: &X) {
+fn f7<Sized? X: T3>(x: &X) {
// This is valid, but the unsized bound on X is irrelevant because any type
// which implements T3 must have statically known size.
let _: Box<X> = T3::f();
fn m1(x: &T4<X>);
fn m2(x: &T5<X>);
}
-trait T5<type X> {
+trait T5<Sized? X> {
// not an error (for now)
fn m1(x: &T4<X>);
fn m2(x: &T5<X>);
fn m1(x: &T4<X>);
fn m2(x: &T5<X>);
}
-trait T7<type X: T> {
+trait T7<Sized? X: T> {
// not an error (for now)
fn m1(x: &T4<X>);
fn m2(x: &T5<X>);
}
// The last field in a struct or variant may be unsized
-struct S2<type X> {
+struct S2<Sized? X> {
f: X,
}
-struct S3<type X> {
+struct S3<Sized? X> {
f1: int,
f2: X,
}
-enum E<type X> {
+enum E<Sized? X> {
V1(X),
V2{x: X},
V3(int, X),
#![no_std]
extern crate std;
extern crate zed = "std";
-extern crate bar = "std#0.11.0";
use std::str;
use x = zed::str;
mod baz {
- pub use bar::str;
pub use x = std::str;
}
// except according to those terms.
pub fn main() {
- assert_eq!((vec!(0i, 1)).to_str(), "[0, 1]".to_string());
- assert_eq!((&[1i, 2]).to_str(), "[1, 2]".to_string());
+ assert_eq!((vec!(0i, 1)).to_string(), "[0, 1]".to_string());
+ assert_eq!((&[1i, 2]).to_string(), "[1, 2]".to_string());
let foo = vec!(3i, 4);
let bar = &[4i, 5];
- assert_eq!(foo.to_str(), "[3, 4]".to_string());
- assert_eq!(bar.to_str(), "[4, 5]".to_string());
+ assert_eq!(foo.to_string(), "[3, 4]".to_string());
+ assert_eq!(bar.to_string(), "[4, 5]".to_string());
}